summaryrefslogtreecommitdiffabout
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--configure.ac4
-rw-r--r--include/opkele/curl.h20
-rw-r--r--include/opkele/types.h39
-rw-r--r--lib/Makefile.am2
-rw-r--r--lib/curl.cc20
-rw-r--r--lib/fields.cc86
-rw-r--r--lib/message.cc (renamed from lib/openid_message.cc)84
-rw-r--r--libopkele.pc.in2
8 files changed, 157 insertions, 100 deletions
diff --git a/configure.ac b/configure.ac
index a49177f..0aa1272 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,253 +1,257 @@
1AC_INIT([libopkele], [1.1.99.0], [libopkele-bugs@klever.net]) 1AC_INIT([libopkele], [1.1.99.0], [libopkele-bugs@klever.net])
2AC_CONFIG_SRCDIR([include/opkele/opkele-config.h]) 2AC_CONFIG_SRCDIR([include/opkele/opkele-config.h])
3AC_CONFIG_HEADERS([config.h include/opkele/acconfig.h]) 3AC_CONFIG_HEADERS([config.h include/opkele/acconfig.h])
4AM_INIT_AUTOMAKE([dist-bzip2]) 4AM_INIT_AUTOMAKE([dist-bzip2])
5 5
6AC_PROG_INSTALL 6AC_PROG_INSTALL
7AC_PROG_CXX 7AC_PROG_CXX
8AC_PROG_CC 8AC_PROG_CC
9AC_PROG_LIBTOOL 9AC_PROG_LIBTOOL
10PKG_PROG_PKG_CONFIG 10PKG_PROG_PKG_CONFIG
11 11
12AC_HEADER_STDC 12AC_HEADER_STDC
13 13
14AC_PATH_PROG([XSLTPROC],[xsltproc],[true]) 14AC_PATH_PROG([XSLTPROC],[xsltproc],[true])
15 15
16AC_MSG_CHECKING([for source tree version]) 16AC_MSG_CHECKING([for source tree version])
17if headrev=$(cd $srcdir && git rev-parse --verify HEAD 2>/dev/null) ; then 17if headrev=$(cd $srcdir && git rev-parse --verify HEAD 2>/dev/null) ; then
18 PACKAGE_SRC_VERSION="$(cd $srcdir && git describe --tags $headrev)" 18 PACKAGE_SRC_VERSION="$(cd $srcdir && git describe --tags $headrev)"
19 test "$PACKAGE_SRC_VERSION" = "$PACKAGE_VERSION" \ 19 test "$PACKAGE_SRC_VERSION" = "$PACKAGE_VERSION" \
20 -o "${PACKAGE_SRC_VERSION#${PACKAGE_VERSION}-}" != "$PACKAGE_SRC_VERSION" || PACKAGE_SRC_VERSION="${PACKAGE_VERSION}:${PACKAGE_SRC_VERSION}" 20 -o "${PACKAGE_SRC_VERSION#${PACKAGE_VERSION}-}" != "$PACKAGE_SRC_VERSION" || PACKAGE_SRC_VERSION="${PACKAGE_VERSION}:${PACKAGE_SRC_VERSION}"
21 ( cd $srcdir && git diff-index $headrev | read dirt ) && PACKAGE_SRC_VERSION="${PACKAGE_SRC_VERSION}-dirty" 21 ( cd $srcdir && git diff-index $headrev | read dirt ) && PACKAGE_SRC_VERSION="${PACKAGE_SRC_VERSION}-dirty"
22else 22else
23 PACKAGE_SRC_VERSION="$PACKAGE_VERSION" 23 PACKAGE_SRC_VERSION="$PACKAGE_VERSION"
24fi 24fi
25AC_MSG_RESULT([$PACKAGE_SRC_VERSION]) 25AC_MSG_RESULT([$PACKAGE_SRC_VERSION])
26AC_SUBST([PACKAGE_SRC_VERSION]) 26AC_SUBST([PACKAGE_SRC_VERSION])
27AC_DEFINE_UNQUOTED([PACKAGE_SRC_VERSION],["$PACKAGE_SRC_VERSION"],[more or less precise source tree version]) 27AC_DEFINE_UNQUOTED([PACKAGE_SRC_VERSION],["$PACKAGE_SRC_VERSION"],[more or less precise source tree version])
28 28
29tr1_mem_std="false" 29tr1_mem_std="false"
30tr1_mem_boost="false" 30tr1_mem_boost="false"
31AC_CHECK_SHAREDPTR(std::tr1,tr1/memory,[ tr1_mem_std=true ]) 31AC_CHECK_SHAREDPTR(std::tr1,tr1/memory,[ tr1_mem_std=true ])
32AC_CHECK_SHAREDPTR(boost,boost/shared_ptr.hpp,[ tr1_mem_boost=true ]) 32AC_CHECK_SHAREDPTR(boost,boost/shared_ptr.hpp,[ tr1_mem_boost=true ])
33tr1_mem="" 33tr1_mem=""
34AC_ARG_WITH([tr1-memory], 34AC_ARG_WITH([tr1-memory],
35 AC_HELP_STRING([--with-tr1-memory=<boost|std>],[select tr1/memory (shared_ptr<>) implementation to use]), 35 AC_HELP_STRING([--with-tr1-memory=<boost|std>],[select tr1/memory (shared_ptr<>) implementation to use]),
36 [ tr1_mem="$withval" ] 36 [ tr1_mem="$withval" ]
37) 37)
38AC_MSG_CHECKING([for tr1/memory implementation to use]) 38AC_MSG_CHECKING([for tr1/memory implementation to use])
39test -z "$tr1_mem" && $tr1_mem_std && tr1_mem=std 39test -z "$tr1_mem" && $tr1_mem_std && tr1_mem=std
40test -z "$tr1_mem" && $tr1_mem_boost && tr1_mem=boost 40test -z "$tr1_mem" && $tr1_mem_boost && tr1_mem=boost
41if test -z "$tr1_mem" ; then 41if test -z "$tr1_mem" ; then
42 AC_MSG_RESULT([none found]) 42 AC_MSG_RESULT([none found])
43else 43else
44 AC_MSG_RESULT([$tr1_mem]) 44 AC_MSG_RESULT([$tr1_mem])
45fi 45fi
46case "$tr1_mem" in 46case "$tr1_mem" in
47 std) 47 std)
48 $tr1_mem_std || AC_MSG_ERROR([std implementation requested, but not found]) 48 $tr1_mem_std || AC_MSG_ERROR([std implementation requested, but not found])
49 OPKELE_TR1_MEM_NS=std::tr1 49 OPKELE_TR1_MEM_NS=std::tr1
50 OPKELE_TR1_MEM_HEADER=tr1/memory 50 OPKELE_TR1_MEM_HEADER=tr1/memory
51 ;; 51 ;;
52 boost) 52 boost)
53 $tr1_mem_boost || AC_MSG_ERROR([boost implementation requested, but not found]) 53 $tr1_mem_boost || AC_MSG_ERROR([boost implementation requested, but not found])
54 OPKELE_TR1_MEM_NS=boost 54 OPKELE_TR1_MEM_NS=boost
55 OPKELE_TR1_MEM_HEADER=boost/shared_ptr.hpp 55 OPKELE_TR1_MEM_HEADER=boost/shared_ptr.hpp
56 ;; 56 ;;
57 *) 57 *)
58 AC_MSG_ERROR([no shared_ptr<> implementation found]) 58 AC_MSG_ERROR([no shared_ptr<> implementation found])
59 ;; 59 ;;
60esac 60esac
61AC_SUBST([OPKELE_TR1_MEM_NS]) 61AC_SUBST([OPKELE_TR1_MEM_NS])
62AC_SUBST([OPKELE_TR1_MEM_HEADER]) 62AC_SUBST([OPKELE_TR1_MEM_HEADER])
63 63
64AC_MSG_CHECKING([for deprecated attribute support]) 64AC_MSG_CHECKING([for deprecated attribute support])
65AC_COMPILE_IFELSE([ 65AC_COMPILE_IFELSE([
66 int __attribute__((deprecated)) deprecated_function(); 66 int __attribute__((deprecated)) deprecated_function();
67 ],[ 67 ],[
68 AC_MSG_RESULT([yes]) 68 AC_MSG_RESULT([yes])
69 AC_DEFINE([OPKELE_DEPRECATE],[__attribute__((deprecated))],[deprecated function attribute]) 69 AC_DEFINE([OPKELE_DEPRECATE],[__attribute__((deprecated))],[deprecated function attribute])
70 ],[ 70 ],[
71 AC_MSG_RESULT([no]) 71 AC_MSG_RESULT([no])
72 AC_DEFINE([OPKELE_DEPRECATE],,[deprecated function attribute]) 72 AC_DEFINE([OPKELE_DEPRECATE],,[deprecated function attribute])
73 ] 73 ]
74) 74)
75 75
76AC_LANG_PUSH([C++]) 76AC_LANG_PUSH([C++])
77AC_MSG_CHECKING([for abi::__cxa_demangle]) 77AC_MSG_CHECKING([for abi::__cxa_demangle])
78AC_COMPILE_IFELSE([ 78AC_COMPILE_IFELSE([
79 #include <typeinfo> 79 #include <typeinfo>
80 using namespace std; 80 using namespace std;
81 #include <cxxabi.h> 81 #include <cxxabi.h>
82 int main(int c,char **v) { 82 int main(int c,char **v) {
83 int dstat; 83 int dstat;
84 char *demangled = abi::__cxa_demangle(typeid(dstat).name(),0,0,&dstat); 84 char *demangled = abi::__cxa_demangle(typeid(dstat).name(),0,0,&dstat);
85 return 0; 85 return 0;
86 } 86 }
87 ],[ 87 ],[
88 AC_MSG_RESULT([yes]) 88 AC_MSG_RESULT([yes])
89 AC_DEFINE([HAVE_DEMANGLE],,[defined if abi::__cxa_demangle is available]) 89 AC_DEFINE([HAVE_DEMANGLE],,[defined if abi::__cxa_demangle is available])
90 ],[ 90 ],[
91 AC_MSG_RESULT([no]) 91 AC_MSG_RESULT([no])
92 ] 92 ]
93) 93)
94AC_LANG_POP([C++]) 94AC_LANG_POP([C++])
95 95
96 96
97 97
98 98
99PKG_CHECK_MODULES([OPENSSL],[openssl],,[ 99PKG_CHECK_MODULES([OPENSSL],[openssl],,[
100 AC_MSG_ERROR([no openssl library found. get one from http://www.openssl.org/]) 100 AC_MSG_ERROR([no openssl library found. get one from http://www.openssl.org/])
101]) 101])
102 102
103WANT_KONFORKA="yes" 103WANT_KONFORKA="yes"
104AC_ARG_ENABLE([konforka], 104AC_ARG_ENABLE([konforka],
105 AC_HELP_STRING([--disable-konforka],[do not use konforka library (default: use if found)]), 105 AC_HELP_STRING([--disable-konforka],[do not use konforka library (default: use if found)]),
106 [ 106 [
107 test "${enableval}" = "no" && WANT_KONFORKA="no" 107 test "${enableval}" = "no" && WANT_KONFORKA="no"
108 ] 108 ]
109) 109)
110if test "${WANT_KONFORKA}" = "yes" ; then 110if test "${WANT_KONFORKA}" = "yes" ; then
111 PKG_CHECK_MODULES([KONFORKA],[konforka],[ 111 PKG_CHECK_MODULES([KONFORKA],[konforka],[
112 AC_SUBST([KONFORKA_CFLAGS]) 112 AC_SUBST([KONFORKA_CFLAGS])
113 AC_SUBST([KONFORKA_LIBS]) 113 AC_SUBST([KONFORKA_LIBS])
114 AC_DEFINE([HAVE_KONFORKA],,[defined in presence of konforka library]) 114 AC_DEFINE([HAVE_KONFORKA],,[defined in presence of konforka library])
115 AC_DEFINE([OPKELE_HAVE_KONFORKA],,[defined in presence of konforka library]) 115 AC_DEFINE([OPKELE_HAVE_KONFORKA],,[defined in presence of konforka library])
116 AC_SUBST([KONFORKA_KONFORKA],[konforka]) 116 AC_SUBST([KONFORKA_KONFORKA],[konforka])
117 ],[true]) 117 ],[true])
118fi 118fi
119 119
120WANT_DOXYGEN="yes" 120WANT_DOXYGEN="yes"
121AC_ARG_ENABLE([doxygen], 121AC_ARG_ENABLE([doxygen],
122 AC_HELP_STRING([--disable-doxygen],[do not generate documentation]), 122 AC_HELP_STRING([--disable-doxygen],[do not generate documentation]),
123 [ 123 [
124 test "${enableval}" = "no" && WANT_DOXYGEN="no" 124 test "${enableval}" = "no" && WANT_DOXYGEN="no"
125 ] 125 ]
126) 126)
127if test "${WANT_DOXYGEN}" = "yes" ; then 127if test "${WANT_DOXYGEN}" = "yes" ; then
128 AC_WITH_DOXYGEN 128 AC_WITH_DOXYGEN
129 AC_WITH_DOT 129 AC_WITH_DOT
130else 130else
131 AM_CONDITIONAL([HAVE_DOXYGEN],[false]) 131 AM_CONDITIONAL([HAVE_DOXYGEN],[false])
132 AM_CONDITIONAL([HAVE_DOT],[false]) 132 AM_CONDITIONAL([HAVE_DOT],[false])
133fi 133fi
134 134
135LIBCURL_CHECK_CONFIG(,,,[ 135LIBCURL_CHECK_CONFIG(,,,[
136 AC_MSG_ERROR([no required libcurl library. get one from http://curl.haxx.se/]) 136 AC_MSG_ERROR([no required libcurl library. get one from http://curl.haxx.se/])
137]) 137])
138 138
139AC_CHECK_HEADER([expat.h],[ 139AC_CHECK_HEADER([expat.h],[
140 AC_CHECK_LIB([expat],[XML_ParserCreate],[ 140 AC_CHECK_LIB([expat],[XML_ParserCreate],[
141 EXPAT_LIBS=-lexpat 141 EXPAT_LIBS=-lexpat
142 EXPAT_CFLAGS= 142 EXPAT_CFLAGS=
143 AC_SUBST([EXPAT_LIBS]) 143 AC_SUBST([EXPAT_LIBS])
144 AC_SUBST([EXPAT_CFLAGS]) 144 AC_SUBST([EXPAT_CFLAGS])
145 ],[ 145 ],[
146 AC_MSG_ERROR([no required expat library. get one from http://expat.sourceforge.net/]) 146 AC_MSG_ERROR([no required expat library. get one from http://expat.sourceforge.net/])
147 ]) 147 ])
148],[ 148],[
149 AC_MSG_ERROR([no required expat library. get one from http://expat.sourceforge.net/]) 149 AC_MSG_ERROR([no required expat library. get one from http://expat.sourceforge.net/])
150]) 150])
151 151
152AC_CHECK_HEADER([tidy.h],[ 152AC_CHECK_HEADER([tidy.h],[
153 AC_CHECK_LIB([tidy],[tidyParseBuffer],[ 153 AC_CHECK_LIB([tidy],[tidyParseBuffer],[
154 TIDY_LIBS=-ltidy 154 TIDY_LIBS=-ltidy
155 TIDY_CFLAGS= 155 TIDY_CFLAGS=
156 AC_SUBST([TIDY_LIBS]) 156 AC_SUBST([TIDY_LIBS])
157 AC_SUBST([TIDY_CFLAGS]) 157 AC_SUBST([TIDY_CFLAGS])
158 ],[ 158 ],[
159 AC_MSG_ERROR([no required htmltidy library found. get one from http://tidy.sourceforge.net/]) 159 AC_MSG_ERROR([no required htmltidy library found. get one from http://tidy.sourceforge.net/])
160 ]) 160 ])
161],[ 161],[
162 AC_MSG_ERROR([no required htmltidy library found. get one from http://tidy.sourceforge.net/]) 162 AC_MSG_ERROR([no required htmltidy library found. get one from http://tidy.sourceforge.net/])
163]) 163])
164 164
165if test -n "$PCRE_LIBS" -a -n "$PCRE_CFLAGS" ; then 165if test -n "$PCRE_LIBS" -a -n "$PCRE_CFLAGS" ; then
166 AC_SUBST([PCRE_CFLAGS]) 166 AC_SUBST([PCRE_CFLAGS])
167 AC_SUBST([PCRE_LIBS]) 167 AC_SUBST([PCRE_LIBS])
168 : 168 :
169else 169else
170 PKG_CHECK_MODULES([PCRE],[libpcre],,[ 170 PKG_CHECK_MODULES([PCRE],[libpcre],,[
171 AC_MSG_ERROR([no libpcre found, go get it at http://www.pcre.org/]) 171 AC_MSG_ERROR([no libpcre found, go get it at http://www.pcre.org/])
172 ]) 172 ])
173fi 173fi
174 174
175PKG_CHECK_MODULES([SQLITE3],[sqlite3],[have_sqlite3=true],[have_sqlite3=false]) 175PKG_CHECK_MODULES([SQLITE3],[sqlite3],[have_sqlite3=true],[have_sqlite3=false])
176AM_CONDITIONAL([HAVE_SQLITE3],[$have_sqlite3]) 176AM_CONDITIONAL([HAVE_SQLITE3],[$have_sqlite3])
177PKG_CHECK_MODULES([KINGATE],[kingate-plaincgi],[have_kingate=true],[have_kingate=false]) 177PKG_CHECK_MODULES([KINGATE],[kingate-plaincgi],[have_kingate=true],[have_kingate=false])
178AM_CONDITIONAL([HAVE_KINGATE],[$have_kingate]) 178AM_CONDITIONAL([HAVE_KINGATE],[$have_kingate])
179PKG_CHECK_MODULES([UUID],[uuid],[have_uuid=true],[have_uuid=false]) 179PKG_CHECK_MODULES([UUID],[uuid],[have_uuid=true],[have_uuid=false])
180AM_CONDITIONAL([HAVE_UUID],[$have_uuid]) 180AM_CONDITIONAL([HAVE_UUID],[$have_uuid])
181if $have_uuid ; then
182 AC_DEFINE([HAVE_LIBUUID],,[defined in presence of libuuid])
183 AC_SUBST([UUID_UUID],[uuid])
184fi
181 185
182curl_ssl_verify_host="true" 186curl_ssl_verify_host="true"
183AC_ARG_ENABLE([ssl-verify-host], 187AC_ARG_ENABLE([ssl-verify-host],
184 AC_HELP_STRING([--disable-ssl-verify-host],[disable cURL cert/host relationships verification]), 188 AC_HELP_STRING([--disable-ssl-verify-host],[disable cURL cert/host relationships verification]),
185 [ test "${enableval}" = "no" && curl_ssl_verify_host="false" ] 189 [ test "${enableval}" = "no" && curl_ssl_verify_host="false" ]
186) 190)
187${curl_ssl_verify_host} || AC_DEFINE([DISABLE_CURL_SSL_VERIFYHOST],,[defined if cURL is not to verify cert/host]) 191${curl_ssl_verify_host} || AC_DEFINE([DISABLE_CURL_SSL_VERIFYHOST],,[defined if cURL is not to verify cert/host])
188 192
189curl_ssl_verify_peer="true" 193curl_ssl_verify_peer="true"
190AC_ARG_ENABLE([ssl-verify-peer], 194AC_ARG_ENABLE([ssl-verify-peer],
191 AC_HELP_STRING([--disable-ssl-verify-peer],[disable cURL cert validity verification]), 195 AC_HELP_STRING([--disable-ssl-verify-peer],[disable cURL cert validity verification]),
192 [ test "${enableval}" = "no" && curl_ssl_verify_peer="false" ] 196 [ test "${enableval}" = "no" && curl_ssl_verify_peer="false" ]
193) 197)
194${curl_ssl_verify_peer} || AC_DEFINE([DISABLE_CURL_SSL_VERIFYPEER],,[defined if cURL is not to verify cert validity]) 198${curl_ssl_verify_peer} || AC_DEFINE([DISABLE_CURL_SSL_VERIFYPEER],,[defined if cURL is not to verify cert validity])
195 199
196postels_law=true 200postels_law=true
197AC_ARG_ENABLE([postels-law], 201AC_ARG_ENABLE([postels-law],
198 AC_HELP_STRING([--disable-postels-law],[Be strict, do not adhere to Postel's Law ("be conservative in what you do, be liberal in what you accept from others", RFC 793)]), 202 AC_HELP_STRING([--disable-postels-law],[Be strict, do not adhere to Postel's Law ("be conservative in what you do, be liberal in what you accept from others", RFC 793)]),
199 [ test "${enableval}" = "no" && postels_law=false ] 203 [ test "${enableval}" = "no" && postels_law=false ]
200) 204)
201$postels_law && AC_DEFINE([POSTELS_LAW],,[defined if we want to adhere to Postel's Law]) 205$postels_law && AC_DEFINE([POSTELS_LAW],,[defined if we want to adhere to Postel's Law])
202 206
203AC_DEFINE_UNQUOTED([OPKELE_SRC_DIR],["$PWD"],[source directory]) 207AC_DEFINE_UNQUOTED([OPKELE_SRC_DIR],["$PWD"],[source directory])
204 208
205nitpick=false 209nitpick=false
206AC_ARG_ENABLE([nitpicking], 210AC_ARG_ENABLE([nitpicking],
207 AC_HELP_STRING([--enable-nitpicking],[make compiler somewhat overly fastidious about the code it deals with]), 211 AC_HELP_STRING([--enable-nitpicking],[make compiler somewhat overly fastidious about the code it deals with]),
208 [ test "$enableval" = "no" || nitpick=true ] 212 [ test "$enableval" = "no" || nitpick=true ]
209) 213)
210if $nitpick ; then 214if $nitpick ; then
211 CPP_NITPICK="-pedantic -Wall -Wextra -Wundef -Wshadow \ 215 CPP_NITPICK="-pedantic -Wall -Wextra -Wundef -Wshadow \
212 -Wunsafe-loop-optimizations -Wconversion -Wmissing-format-attribute \ 216 -Wunsafe-loop-optimizations -Wconversion -Wmissing-format-attribute \
213 -Wredundant-decls -ansi" 217 -Wredundant-decls -ansi"
214 # -Wlogical-op -Wmissing-noreturn 218 # -Wlogical-op -Wmissing-noreturn
215 C_NITPICK="$CPP_NITPICK" 219 C_NITPICK="$CPP_NITPICK"
216 CXX_NITPICK="$C_NITPICK" 220 CXX_NITPICK="$C_NITPICK"
217 221
218 CPPFLAGS="$CPPFLAGS $CPP_NITPICK" 222 CPPFLAGS="$CPPFLAGS $CPP_NITPICK"
219 CFLAGS="$CFLAGS $C_NITPICK" 223 CFLAGS="$CFLAGS $C_NITPICK"
220 CXXFLAGS="$CXXFLAGS $CXX_NITPICK" 224 CXXFLAGS="$CXXFLAGS $CXX_NITPICK"
221fi 225fi
222 226
223ndebug=true 227ndebug=true
224AC_ARG_ENABLE([debug], 228AC_ARG_ENABLE([debug],
225 AC_HELP_STRING([--enable-debug],[enable debugging code]), 229 AC_HELP_STRING([--enable-debug],[enable debugging code]),
226 [ test "$enableval" = "no" || ndebug=false ] 230 [ test "$enableval" = "no" || ndebug=false ]
227) 231)
228if $ndebug ; then 232if $ndebug ; then
229 CPPFLAGS_DEBUG="-DNDEBUG" 233 CPPFLAGS_DEBUG="-DNDEBUG"
230else 234else
231 CPPFLAGS_DEBUG="" 235 CPPFLAGS_DEBUG=""
232fi 236fi
233AC_SUBST([CPPFLAGS_DEBUG]) 237AC_SUBST([CPPFLAGS_DEBUG])
234 238
235xri_proxy_url="https://xri.net/" 239xri_proxy_url="https://xri.net/"
236AC_MSG_CHECKING([for XRI resolver proxy]) 240AC_MSG_CHECKING([for XRI resolver proxy])
237AC_ARG_ENABLE([xri-proxy], 241AC_ARG_ENABLE([xri-proxy],
238 AC_HELP_STRING([--with-xri-proxy=url],[set xri proxy for use when resolving xri identities, default is https://xri.net/]), 242 AC_HELP_STRING([--with-xri-proxy=url],[set xri proxy for use when resolving xri identities, default is https://xri.net/]),
239 [ xri_proxy_url="$withval" ] 243 [ xri_proxy_url="$withval" ]
240) 244)
241AC_MSG_RESULT([$xri_proxy_url]) 245AC_MSG_RESULT([$xri_proxy_url])
242AC_DEFINE_UNQUOTED([XRI_PROXY_URL],["$xri_proxy_url"],[XRI proxy resolver URL]) 246AC_DEFINE_UNQUOTED([XRI_PROXY_URL],["$xri_proxy_url"],[XRI proxy resolver URL])
243 247
244AC_CONFIG_FILES([ 248AC_CONFIG_FILES([
245 Makefile 249 Makefile
246 libopkele.pc 250 libopkele.pc
247 Doxyfile 251 Doxyfile
248 include/Makefile 252 include/Makefile
249 include/opkele/tr1-mem.h 253 include/opkele/tr1-mem.h
250 lib/Makefile 254 lib/Makefile
251 test/Makefile 255 test/Makefile
252]) 256])
253AC_OUTPUT 257AC_OUTPUT
diff --git a/include/opkele/curl.h b/include/opkele/curl.h
index 5cf8e48..bcaf11d 100644
--- a/include/opkele/curl.h
+++ b/include/opkele/curl.h
@@ -1,72 +1,92 @@
1#ifndef __OPKELE_CURL_H 1#ifndef __OPKELE_CURL_H
2#define __OPKELE_CURL_H 2#define __OPKELE_CURL_H
3 3
4#include <cassert> 4#include <cassert>
5#include <string> 5#include <string>
6#include <algorithm> 6#include <algorithm>
7#include <curl/curl.h> 7#include <curl/curl.h>
8 8
9namespace opkele { 9namespace opkele {
10 using std::min; 10 using std::min;
11 using std::string; 11 using std::string;
12 12
13 namespace util { 13 namespace util {
14 14
15 class curl_slist_t {
16 public:
17 curl_slist *_s;
18
19 curl_slist_t() : _s(0) { }
20 curl_slist_t(curl_slist *s) : _s(s) { }
21 virtual ~curl_slist_t() throw();
22
23 curl_slist_t& operator=(curl_slist *s);
24
25 operator const curl_slist*(void) const { return _s; }
26 operator curl_slist*(void) { return _s; }
27
28 void append(const char *str);
29 void append(const string& str) {
30 append(str.c_str()); }
31 };
32
15 class curl_t { 33 class curl_t {
16 public: 34 public:
17 CURL *_c; 35 CURL *_c;
18 36
19 curl_t() : _c(0) { } 37 curl_t() : _c(0) { }
20 curl_t(CURL *c) : _c(c) { } 38 curl_t(CURL *c) : _c(c) { }
21 virtual ~curl_t() throw(); 39 virtual ~curl_t() throw();
22 40
23 curl_t& operator=(CURL *c); 41 curl_t& operator=(CURL *c);
24 42
25 operator const CURL*(void) const { return _c; } 43 operator const CURL*(void) const { return _c; }
26 operator CURL*(void) { return _c; } 44 operator CURL*(void) { return _c; }
27 45
28 CURLcode misc_sets(); 46 CURLcode misc_sets();
29 47
30 template<typename PT> 48 template<typename PT>
31 inline CURLcode easy_setopt(CURLoption o,PT p) { assert(_c); return curl_easy_setopt(_c,o,p); } 49 inline CURLcode easy_setopt(CURLoption o,PT p) { assert(_c); return curl_easy_setopt(_c,o,p); }
50 inline CURLcode easy_setopt(CURLoption o,const curl_slist_t& p) {
51 assert(_c); return curl_easy_setopt(_c,o,(const curl_slist*)p); }
32 CURLcode easy_perform() { assert(_c); return curl_easy_perform(_c); } 52 CURLcode easy_perform() { assert(_c); return curl_easy_perform(_c); }
33 template<typename IT> 53 template<typename IT>
34 inline CURLcode easy_getinfo(CURLINFO i,IT p) { assert(_c); return curl_easy_getinfo(_c,i,p); } 54 inline CURLcode easy_getinfo(CURLINFO i,IT p) { assert(_c); return curl_easy_getinfo(_c,i,p); }
35 55
36 static inline CURL *easy_init() { return curl_easy_init(); } 56 static inline CURL *easy_init() { return curl_easy_init(); }
37 57
38 virtual size_t write(void* /* p */,size_t /* s */,size_t /* nm */) { return 0; } 58 virtual size_t write(void* /* p */,size_t /* s */,size_t /* nm */) { return 0; }
39 CURLcode set_write(); 59 CURLcode set_write();
40 60
41 virtual int progress(double /* dlt */,double /* dln*/ ,double /* ult */,double /* uln */) { return 0; } 61 virtual int progress(double /* dlt */,double /* dln*/ ,double /* ult */,double /* uln */) { return 0; }
42 CURLcode set_progress(); 62 CURLcode set_progress();
43 63
44 virtual size_t header(void* /* p */,size_t s,size_t nm) { return s*nm; } 64 virtual size_t header(void* /* p */,size_t s,size_t nm) { return s*nm; }
45 CURLcode set_header(); 65 CURLcode set_header();
46 }; 66 };
47 67
48 template<int lim> 68 template<int lim>
49 class curl_fetch_string_t : public curl_t { 69 class curl_fetch_string_t : public curl_t {
50 public: 70 public:
51 curl_fetch_string_t(CURL *c) 71 curl_fetch_string_t(CURL *c)
52 : curl_t(c) { } 72 : curl_t(c) { }
53 ~curl_fetch_string_t() throw() { } 73 ~curl_fetch_string_t() throw() { }
54 74
55 string response; 75 string response;
56 76
57 size_t write(void *p,size_t size,size_t nmemb) { 77 size_t write(void *p,size_t size,size_t nmemb) {
58 size_t bytes = size*nmemb; 78 size_t bytes = size*nmemb;
59 size_t get = min(lim-response.length(),bytes); 79 size_t get = min(lim-response.length(),bytes);
60 response.append((const char *)p,get); 80 response.append((const char *)p,get);
61 return get; 81 return get;
62 } 82 }
63 }; 83 };
64 84
65 typedef curl_fetch_string_t<16384> curl_pick_t; 85 typedef curl_fetch_string_t<16384> curl_pick_t;
66 86
67 87
68 } 88 }
69 89
70} 90}
71 91
72#endif /* __OPKELE_CURL_H */ 92#endif /* __OPKELE_CURL_H */
diff --git a/include/opkele/types.h b/include/opkele/types.h
index ffb9afb..f63bf5d 100644
--- a/include/opkele/types.h
+++ b/include/opkele/types.h
@@ -1,234 +1,243 @@
1#ifndef __OPKELE_TYPES_H 1#ifndef __OPKELE_TYPES_H
2#define __OPKELE_TYPES_H 2#define __OPKELE_TYPES_H
3 3
4/** 4/**
5 * @file 5 * @file
6 * @brief various types declarations 6 * @brief various types declarations
7 */ 7 */
8 8
9#include <cstring> 9#include <cstring>
10#include <ostream> 10#include <ostream>
11#include <vector> 11#include <vector>
12#include <string> 12#include <string>
13#include <map> 13#include <map>
14#include <set> 14#include <set>
15#include <list> 15#include <list>
16#include <opkele/iterator.h> 16#include <opkele/iterator.h>
17#include <opkele/tr1-mem.h> 17#include <opkele/tr1-mem.h>
18 18
19namespace opkele { 19namespace opkele {
20 using std::vector; 20 using std::vector;
21 using std::string; 21 using std::string;
22 using std::map; 22 using std::map;
23 using std::ostream; 23 using std::ostream;
24 using std::multimap; 24 using std::multimap;
25 using std::set; 25 using std::set;
26 using std::list; 26 using std::list;
27 using std::iterator; 27 using std::iterator;
28 using std::forward_iterator_tag; 28 using std::forward_iterator_tag;
29 29
30 /** 30 /**
31 * the OpenID operation mode 31 * the OpenID operation mode
32 */ 32 */
33 typedef enum _mode_t { 33 typedef enum _mode_t {
34 mode_unknown = 0, 34 mode_unknown = 0,
35 mode_associate, 35 mode_associate,
36 mode_checkid_immediate, 36 mode_checkid_immediate,
37 mode_checkid_setup, 37 mode_checkid_setup,
38 mode_check_association 38 mode_check_association
39 } mode_t; 39 } mode_t;
40 40
41 /** 41 /**
42 * the association secret container 42 * the association secret container
43 */ 43 */
44 class secret_t : public vector<unsigned char> { 44 class secret_t : public vector<unsigned char> {
45 public: 45 public:
46 46
47 /** 47 /**
48 * xor the secret and hmac together and encode, using base64 48 * xor the secret and hmac together and encode, using base64
49 * @param key_d pointer to the message digest 49 * @param key_d pointer to the message digest
50 * @param rv reference to the return value 50 * @param rv reference to the return value
51 */ 51 */
52 void enxor_to_base64(const unsigned char *key_d,string& rv) const; 52 void enxor_to_base64(const unsigned char *key_d,string& rv) const;
53 /** 53 /**
54 * decode base64-encoded secret and xor it with the message digest 54 * decode base64-encoded secret and xor it with the message digest
55 * @param key_d pointer to the message digest 55 * @param key_d pointer to the message digest
56 * @param b64 base64-encoded secret value 56 * @param b64 base64-encoded secret value
57 */ 57 */
58 void enxor_from_base64(const unsigned char *key_d,const string& b64); 58 void enxor_from_base64(const unsigned char *key_d,const string& b64);
59 /** 59 /**
60 * plainly encode to base64 representation 60 * plainly encode to base64 representation
61 * @param rv reference to the return value 61 * @param rv reference to the return value
62 */ 62 */
63 void to_base64(string& rv) const; 63 void to_base64(string& rv) const;
64 /** 64 /**
65 * decode cleartext secret from base64 65 * decode cleartext secret from base64
66 * @param b64 base64-encoded representation of the secret value 66 * @param b64 base64-encoded representation of the secret value
67 */ 67 */
68 void from_base64(const string& b64); 68 void from_base64(const string& b64);
69 }; 69 };
70 70
71 /** 71 /**
72 * Interface to the association. 72 * Interface to the association.
73 */ 73 */
74 class association_t { 74 class association_t {
75 public: 75 public:
76 76
77 virtual ~association_t() { } 77 virtual ~association_t() { }
78 78
79 /** 79 /**
80 * retrieve the server with which association was established. 80 * retrieve the server with which association was established.
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_fields {
122 public: 122 public:
123 typedef list<string> fields_t;
124 typedef util::forward_iterator_proxy< 123 typedef util::forward_iterator_proxy<
125 string,const string&,const string* 124 string,const string&,const string*
126 > fields_iterator; 125 > fields_iterator;
127 126
128 basic_openid_message() { } 127 basic_fields() { }
129 virtual ~basic_openid_message() { } 128 virtual ~basic_fields() { }
130 basic_openid_message(const basic_openid_message& x); 129 basic_fields(const basic_fields& x);
131 void copy_to(basic_openid_message& x) const; 130 void copy_to(basic_fields& x) const;
132 void append_to(basic_openid_message& x) const; 131 void append_to(basic_fields& x) const;
133 132
134 virtual bool has_field(const string& n) const = 0; 133 virtual bool has_field(const string& n) const = 0;
135 virtual const string& get_field(const string& n) const = 0; 134 virtual const string& get_field(const string& n) const = 0;
136 135
137 virtual bool has_ns(const string& uri) const;
138 virtual string get_ns(const string& uri) const;
139
140 virtual fields_iterator fields_begin() const = 0; 136 virtual fields_iterator fields_begin() const = 0;
141 virtual fields_iterator fields_end() const = 0; 137 virtual fields_iterator fields_end() const = 0;
142 138
143 virtual string append_query(const string& url,const char *pfx="openid.") const; 139 virtual string append_query(const string& url,const char *pfx=0) const;
144 virtual string query_string(const char *pfx="openid.") const; 140 virtual string query_string(const char *pfx=0) const;
145
146 141
147 virtual void reset_fields(); 142 virtual void reset_fields();
148 virtual void set_field(const string& n,const string& v); 143 virtual void set_field(const string& n,const string& v);
149 virtual void reset_field(const string& n); 144 virtual void reset_field(const string& n);
150 145
146 };
147
148 class basic_openid_message : public basic_fields {
149 public:
150
151 basic_openid_message() { }
152 basic_openid_message(const basic_openid_message& x);
153
154 virtual bool has_ns(const string& uri) const;
155 virtual string get_ns(const string& uri) const;
156
157 virtual string append_query(const string& url,const char *pfx="openid.") const {
158 return basic_fields::append_query(url,pfx); }
159 virtual string query_string(const char *pfx="openid.") const {
160 return basic_fields::query_string(pfx); }
161
151 virtual void from_keyvalues(const string& kv); 162 virtual void from_keyvalues(const string& kv);
152 virtual void to_keyvalues(ostream& o) const; 163 virtual void to_keyvalues(ostream& o) const;
153 164
154 virtual void to_htmlhiddens(ostream& o,const char* pfx=0) const; 165 virtual void to_htmlhiddens(ostream& o,const char* pfx=0) const;
155 166
156 void add_to_signed(const string& fields); 167 void add_to_signed(const string& fields);
157 string find_ns(const string& uri,const char *pfx) const; 168 string find_ns(const string& uri,const char *pfx) const;
158 string allocate_ns(const string& uri,const char *pfx); 169 string allocate_ns(const string& uri,const char *pfx);
159 }; 170 };
160 171
161 class openid_message_t : public basic_openid_message, public map<string,string> { 172 class openid_message_t : public basic_openid_message, public map<string,string> {
162 public: 173 public:
163 openid_message_t() { } 174 openid_message_t() { }
164 openid_message_t(const basic_openid_message& x) 175 openid_message_t(const basic_openid_message& x)
165 : basic_openid_message(x) { } 176 : basic_openid_message(x) { }
166 177
167 void copy_to(basic_openid_message& x) const;
168
169 bool has_field(const string& n) const; 178 bool has_field(const string& n) const;
170 const string& get_field(const string& n) const; 179 const string& get_field(const string& n) const;
171 virtual fields_iterator fields_begin() const; 180 virtual fields_iterator fields_begin() const;
172 virtual fields_iterator fields_end() const; 181 virtual fields_iterator fields_end() const;
173 182
174 void reset_fields(); 183 void reset_fields();
175 void set_field(const string& n,const string& v); 184 void set_field(const string& n,const string& v);
176 void reset_field(const string& n); 185 void reset_field(const string& n);
177 }; 186 };
178 187
179 /** 188 /**
180 * request/response parameters map 189 * request/response parameters map
181 */ 190 */
182 class params_t : public openid_message_t { 191 class params_t : public openid_message_t {
183 public: 192 public:
184 193
185 /** 194 /**
186 * check whether the parameter is present. 195 * check whether the parameter is present.
187 * @param n the parameter name 196 * @param n the parameter name
188 * @return true if yes 197 * @return true if yes
189 */ 198 */
190 bool has_param(const string& n) const { 199 bool has_param(const string& n) const {
191 return has_field(n); } 200 return has_field(n); }
192 /** 201 /**
193 * retrieve the parameter (const version) 202 * retrieve the parameter (const version)
194 * @param n the parameter name 203 * @param n the parameter name
195 * @return the parameter value 204 * @return the parameter value
196 * @throw failed_lookup if there is no such parameter 205 * @throw failed_lookup if there is no such parameter
197 */ 206 */
198 const string& get_param(const string& n) const { 207 const string& get_param(const string& n) const {
199 return get_field(n); } 208 return get_field(n); }
200 209
201 /** 210 /**
202 * parse the OpenID key/value data. 211 * parse the OpenID key/value data.
203 * @param kv the OpenID key/value data 212 * @param kv the OpenID key/value data
204 */ 213 */
205 void parse_keyvalues(const string& kv) { 214 void parse_keyvalues(const string& kv) {
206 from_keyvalues(kv); } 215 from_keyvalues(kv); }
207 216
208 string append_query(const string& url,const char *prefix="openid.") const; 217 string append_query(const string& url,const char *prefix="openid.") const;
209 218
210 }; 219 };
211 220
212 struct openid_endpoint_t { 221 struct openid_endpoint_t {
213 string uri; 222 string uri;
214 string claimed_id; 223 string claimed_id;
215 string local_id; 224 string local_id;
216 225
217 openid_endpoint_t() { } 226 openid_endpoint_t() { }
218 openid_endpoint_t(const string& u,const string& cid,const string& lid) 227 openid_endpoint_t(const string& u,const string& cid,const string& lid)
219 : uri(u), claimed_id(cid), local_id(lid) { } 228 : uri(u), claimed_id(cid), local_id(lid) { }
220 229
221 bool operator==(const openid_endpoint_t& x) const { 230 bool operator==(const openid_endpoint_t& x) const {
222 return uri==x.uri && local_id==x.local_id; } 231 return uri==x.uri && local_id==x.local_id; }
223 bool operator<(const openid_endpoint_t& x) const { 232 bool operator<(const openid_endpoint_t& x) const {
224 int c; 233 int c;
225 return (c=strcmp(uri.c_str(),x.uri.c_str())) 234 return (c=strcmp(uri.c_str(),x.uri.c_str()))
226 ? (c<0) : (strcmp(local_id.c_str(),x.local_id.c_str())<0); } 235 ? (c<0) : (strcmp(local_id.c_str(),x.local_id.c_str())<0); }
227 }; 236 };
228 237
229 typedef util::output_iterator_proxy<openid_endpoint_t> 238 typedef util::output_iterator_proxy<openid_endpoint_t>
230 openid_endpoint_output_iterator; 239 openid_endpoint_output_iterator;
231 240
232} 241}
233 242
234#endif /* __OPKELE_TYPES_H */ 243#endif /* __OPKELE_TYPES_H */
diff --git a/lib/Makefile.am b/lib/Makefile.am
index e8bfbf5..20d15b8 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -1,34 +1,34 @@
1lib_LTLIBRARIES = libopkele.la 1lib_LTLIBRARIES = libopkele.la
2 2
3AM_CPPFLAGS = ${CPPFLAGS_DEBUG} 3AM_CPPFLAGS = ${CPPFLAGS_DEBUG}
4DEFAULT_INCLUDES = -I${top_builddir} 4DEFAULT_INCLUDES = -I${top_builddir}
5INCLUDES = \ 5INCLUDES = \
6 -I${top_builddir}/include/ -I${top_srcdir}/include/ \ 6 -I${top_builddir}/include/ -I${top_srcdir}/include/ \
7 ${KONFORKA_CFLAGS} \ 7 ${KONFORKA_CFLAGS} \
8 ${OPENSSL_CFLAGS} \ 8 ${OPENSSL_CFLAGS} \
9 ${LIBCURL_CPPFLAGS} \ 9 ${LIBCURL_CPPFLAGS} \
10 ${PCRE_CFLAGS} ${EXPAT_CFLAGS} ${TIDY_CFLAGS} 10 ${PCRE_CFLAGS} ${EXPAT_CFLAGS} ${TIDY_CFLAGS}
11libopkele_la_LIBADD = \ 11libopkele_la_LIBADD = \
12 ${LIBCURL} \ 12 ${LIBCURL} \
13 ${PCRE_LIBS} ${EXPAT_LIBS} \ 13 ${PCRE_LIBS} ${EXPAT_LIBS} \
14 ${OPENSSL_LIBS} \ 14 ${OPENSSL_LIBS} \
15 ${KONFORKA_LIBS} ${TIDY_LIBS} 15 ${KONFORKA_LIBS} ${TIDY_LIBS}
16 16
17libopkele_la_SOURCES = \ 17libopkele_la_SOURCES = \
18 params.cc \ 18 params.cc \
19 util.cc \ 19 util.cc \
20 server.cc \ 20 server.cc \
21 secret.cc \ 21 secret.cc \
22 data.cc \ 22 data.cc \
23 consumer.cc \ 23 consumer.cc \
24 exception.cc \ 24 exception.cc \
25 extension.cc \ 25 extension.cc \
26 sreg.cc \ 26 sreg.cc \
27 extension_chain.cc \ 27 extension_chain.cc \
28 curl.cc expat.cc \ 28 curl.cc expat.cc \
29 discovery.cc \ 29 discovery.cc \
30 basic_rp.cc prequeue_rp.cc \ 30 basic_rp.cc prequeue_rp.cc \
31 openid_message.cc \ 31 fields.cc message.cc \
32 basic_op.cc verify_op.cc 32 basic_op.cc verify_op.cc
33libopkele_la_LDFLAGS = \ 33libopkele_la_LDFLAGS = \
34 -version-info 2:0:0 34 -version-info 2:0:0
diff --git a/lib/curl.cc b/lib/curl.cc
index 6172828..734e2ca 100644
--- a/lib/curl.cc
+++ b/lib/curl.cc
@@ -1,79 +1,99 @@
1#include <opkele/exception.h>
1#include <opkele/curl.h> 2#include <opkele/curl.h>
2 3
3#include "config.h" 4#include "config.h"
4 5
5namespace opkele { 6namespace opkele {
6 7
7 namespace util { 8 namespace util {
8 9
10 curl_slist_t::~curl_slist_t() throw() {
11 if(_s)
12 curl_slist_free_all(_s);
13 }
14
15 curl_slist_t& curl_slist_t::operator=(curl_slist *s) {
16 if(_s)
17 curl_slist_free_all(_s);
18 _s = s;
19 return *this;
20 }
21
22 void curl_slist_t::append(const char *str) {
23 curl_slist *s = curl_slist_append(_s,str);
24 if(!s)
25 throw opkele::exception(OPKELE_CP_ "failed to curl_slist_append()");
26 _s=s;
27 }
28
9 curl_t::~curl_t() throw() { 29 curl_t::~curl_t() throw() {
10 if(_c) 30 if(_c)
11 curl_easy_cleanup(_c); 31 curl_easy_cleanup(_c);
12 } 32 }
13 33
14 curl_t& curl_t::operator=(CURL *c) { 34 curl_t& curl_t::operator=(CURL *c) {
15 if(_c) 35 if(_c)
16 curl_easy_cleanup(_c); 36 curl_easy_cleanup(_c);
17 _c = c; 37 _c = c;
18 return *this; 38 return *this;
19 } 39 }
20 40
21 CURLcode curl_t::misc_sets() { 41 CURLcode curl_t::misc_sets() {
22 assert(_c); 42 assert(_c);
23 CURLcode r; 43 CURLcode r;
24 (r=easy_setopt(CURLOPT_FOLLOWLOCATION,1)) 44 (r=easy_setopt(CURLOPT_FOLLOWLOCATION,1))
25 || (r=easy_setopt(CURLOPT_MAXREDIRS,5)) 45 || (r=easy_setopt(CURLOPT_MAXREDIRS,5))
26 || (r=easy_setopt(CURLOPT_DNS_CACHE_TIMEOUT,120)) 46 || (r=easy_setopt(CURLOPT_DNS_CACHE_TIMEOUT,120))
27 || (r=easy_setopt(CURLOPT_DNS_USE_GLOBAL_CACHE,1)) 47 || (r=easy_setopt(CURLOPT_DNS_USE_GLOBAL_CACHE,1))
28 || (r=easy_setopt(CURLOPT_USERAGENT,PACKAGE_NAME"/"PACKAGE_SRC_VERSION)) 48 || (r=easy_setopt(CURLOPT_USERAGENT,PACKAGE_NAME"/"PACKAGE_SRC_VERSION))
29 || (r=easy_setopt(CURLOPT_TIMEOUT,20)) 49 || (r=easy_setopt(CURLOPT_TIMEOUT,20))
30 #ifdefDISABLE_CURL_SSL_VERIFYHOST 50 #ifdefDISABLE_CURL_SSL_VERIFYHOST
31 || (r=easy_setopt(CURLOPT_SSL_VERIFYHOST,0)) 51 || (r=easy_setopt(CURLOPT_SSL_VERIFYHOST,0))
32#endif 52#endif
33 #ifdefDISABLE_CURL_SSL_VERIFYPEER 53 #ifdefDISABLE_CURL_SSL_VERIFYPEER
34 || (r=easy_setopt(CURLOPT_SSL_VERIFYPEER,0)) 54 || (r=easy_setopt(CURLOPT_SSL_VERIFYPEER,0))
35#endif 55#endif
36 ; 56 ;
37 return r; 57 return r;
38 } 58 }
39 59
40 static size_t _write(void *p,size_t s,size_t nm,void *stream) { 60 static size_t _write(void *p,size_t s,size_t nm,void *stream) {
41 return ((curl_t*)stream)->write(p,s,nm); 61 return ((curl_t*)stream)->write(p,s,nm);
42 } 62 }
43 63
44 CURLcode curl_t::set_write() { 64 CURLcode curl_t::set_write() {
45 assert(_c); 65 assert(_c);
46 CURLcode r; 66 CURLcode r;
47 (r = easy_setopt(CURLOPT_WRITEDATA,this)) 67 (r = easy_setopt(CURLOPT_WRITEDATA,this))
48 || (r = easy_setopt(CURLOPT_WRITEFUNCTION,_write)); 68 || (r = easy_setopt(CURLOPT_WRITEFUNCTION,_write));
49 return r; 69 return r;
50 } 70 }
51 71
52 static int _progress(void *cp,double dlt,double dln,double ult,double uln) { 72 static int _progress(void *cp,double dlt,double dln,double ult,double uln) {
53 return ((curl_t*)cp)->progress(dlt,dln,ult,uln); 73 return ((curl_t*)cp)->progress(dlt,dln,ult,uln);
54 } 74 }
55 75
56 CURLcode curl_t::set_progress() { 76 CURLcode curl_t::set_progress() {
57 assert(_c); 77 assert(_c);
58 CURLcode r; 78 CURLcode r;
59 (r = easy_setopt(CURLOPT_PROGRESSDATA,this)) 79 (r = easy_setopt(CURLOPT_PROGRESSDATA,this))
60 || (r = easy_setopt(CURLOPT_PROGRESSFUNCTION,_progress)) 80 || (r = easy_setopt(CURLOPT_PROGRESSFUNCTION,_progress))
61 || (r = easy_setopt(CURLOPT_NOPROGRESS,0)); 81 || (r = easy_setopt(CURLOPT_NOPROGRESS,0));
62 return r; 82 return r;
63 } 83 }
64 84
65 static size_t _header(void *p,size_t s,size_t nm,void *stream) { 85 static size_t _header(void *p,size_t s,size_t nm,void *stream) {
66 return ((curl_t*)stream)->header(p,s,nm); 86 return ((curl_t*)stream)->header(p,s,nm);
67 } 87 }
68 88
69 CURLcode curl_t::set_header() { 89 CURLcode curl_t::set_header() {
70 assert(_c); 90 assert(_c);
71 CURLcode r; 91 CURLcode r;
72 (r = easy_setopt(CURLOPT_HEADERDATA,this)) 92 (r = easy_setopt(CURLOPT_HEADERDATA,this))
73 || (r=easy_setopt(CURLOPT_HEADERFUNCTION,_header)); 93 || (r=easy_setopt(CURLOPT_HEADERFUNCTION,_header));
74 return r; 94 return r;
75 } 95 }
76 96
77 } 97 }
78 98
79} 99}
diff --git a/lib/fields.cc b/lib/fields.cc
new file mode 100644
index 0000000..d494098
--- a/dev/null
+++ b/lib/fields.cc
@@ -0,0 +1,86 @@
1#include <opkele/types.h>
2#include <opkele/exception.h>
3#include <opkele/util.h>
4
5namespace opkele {
6 using std::unary_function;
7
8 struct __om_copier : public unary_function<const string&,void> {
9 public:
10 const basic_fields& from;
11 basic_fields& to;
12
13 __om_copier(basic_fields& t,const basic_fields& f)
14 : from(f), to(t) { }
15
16 result_type operator()(argument_type f) {
17 to.set_field(f,from.get_field(f)); }
18 };
19
20 basic_fields::basic_fields(const basic_fields& x) {
21 x.copy_to(*this);
22 }
23 void basic_fields::copy_to(basic_fields& x) const {
24 x.reset_fields();
25 for_each(fields_begin(),fields_end(),
26 __om_copier(x,*this) );
27 }
28 void basic_fields::append_to(basic_fields& x) const {
29 for_each(fields_begin(),fields_end(),
30 __om_copier(x,*this) );
31 }
32
33 struct __om_query_builder : public unary_function<const string&,void> {
34 public:
35 const basic_fields& om;
36 bool first;
37 string& rv;
38 const char *pfx;
39
40 __om_query_builder(const char *p,string& r,const basic_fields& m)
41 : om(m), first(true), rv(r), pfx(p) {
42 for_each(om.fields_begin(),om.fields_end(),*this);
43 }
44 __om_query_builder(const char *p,string& r,const basic_fields& m,const string& u)
45 : om(m), first(true), rv(r), pfx(p) {
46 rv = u;
47 if(rv.find('?')==string::npos)
48 rv += '?';
49 else
50 first = false;
51 for_each(om.fields_begin(),om.fields_end(),*this);
52 }
53
54 result_type operator()(argument_type f) {
55 if(first)
56 first = false;
57 else
58 rv += '&';
59 if(pfx) rv += pfx;
60 rv+= f;
61 rv += '=';
62 rv += util::url_encode(om.get_field(f));
63 }
64 };
65
66 string basic_fields::append_query(const string& url,const char *pfx) const {
67 string rv;
68 return __om_query_builder(pfx,rv,*this,url).rv;
69 }
70 string basic_fields::query_string(const char *pfx) const {
71 string rv;
72 return __om_query_builder(pfx,rv,*this).rv;
73 }
74
75 void basic_fields::reset_fields() {
76 throw not_implemented(OPKELE_CP_ "reset_fields() not implemented");
77 }
78 void basic_fields::set_field(const string&,const string&) {
79 throw not_implemented(OPKELE_CP_ "set_field() not implemented");
80 }
81 void basic_fields::reset_field(const string&) {
82 throw not_implemented(OPKELE_CP_ "reset_field() not implemented");
83 }
84
85
86}
diff --git a/lib/openid_message.cc b/lib/message.cc
index e244f43..b2324b7 100644
--- a/lib/openid_message.cc
+++ b/lib/message.cc
@@ -1,276 +1,194 @@
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> {
14 public:
15 const basic_openid_message& from;
16 basic_openid_message& to;
17
18 __om_copier(basic_openid_message& t,const basic_openid_message& f)
19 : from(f), to(t) { }
20
21 result_type operator()(argument_type f) {
22 to.set_field(f,from.get_field(f)); }
23 };
24
25 basic_openid_message::basic_openid_message(const basic_openid_message& x) {
26 x.copy_to(*this);
27 }
28 void basic_openid_message::copy_to(basic_openid_message& x) const {
29 x.reset_fields();
30 for_each(fields_begin(),fields_end(),
31 __om_copier(x,*this) );
32 }
33 void basic_openid_message::append_to(basic_openid_message& x) const {
34 for_each(fields_begin(),fields_end(),
35 __om_copier(x,*this) );
36 }
37 13
38 struct __om_ns_finder : public unary_function<const string&,bool> { 14 struct __om_ns_finder : public unary_function<const string&,bool> {
39 public: 15 public:
40 const basic_openid_message& om; 16 const basic_openid_message& om;
41 const string& uri; 17 const string& uri;
42 18
43 __om_ns_finder(const basic_openid_message& m, 19 __om_ns_finder(const basic_openid_message& m,
44 const string& u) : om(m), uri(u) { } 20 const string& u) : om(m), uri(u) { }
45 21
46 result_type operator()(argument_type f) { 22 result_type operator()(argument_type f) {
47 return 23 return
48 (!strncmp(f.c_str(),"ns.",sizeof("ns.")-1)) 24 (!strncmp(f.c_str(),"ns.",sizeof("ns.")-1))
49 && om.get_field(f)==uri ; 25 && om.get_field(f)==uri ;
50 } 26 }
51 }; 27 };
52 28
53 bool basic_openid_message::has_ns(const string& uri) const { 29 bool basic_openid_message::has_ns(const string& uri) const {
54 fields_iterator ei = fields_end(); 30 fields_iterator ei = fields_end();
55 fields_iterator i = find_if(fields_begin(),fields_end(), 31 fields_iterator i = find_if(fields_begin(),fields_end(),
56 __om_ns_finder(*this,uri)); 32 __om_ns_finder(*this,uri));
57 return !(i==ei); 33 return !(i==ei);
58 } 34 }
59 string basic_openid_message::get_ns(const string& uri) const { 35 string basic_openid_message::get_ns(const string& uri) const {
60 fields_iterator ei = fields_end(); 36 fields_iterator ei = fields_end();
61 fields_iterator i = find_if(fields_begin(),fields_end(), 37 fields_iterator i = find_if(fields_begin(),fields_end(),
62 __om_ns_finder(*this,uri)); 38 __om_ns_finder(*this,uri));
63 if(i==ei) 39 if(i==ei)
64 throw failed_lookup(OPKELE_CP_ string("failed to find namespace ")+uri); 40 throw failed_lookup(OPKELE_CP_ string("failed to find namespace ")+uri);
65 return i->substr(3); 41 return i->substr(3);
66 } 42 }
67 43
68 struct __om_query_builder : public unary_function<const string&,void> {
69 public:
70 const basic_openid_message& om;
71 bool first;
72 string& rv;
73 const char *pfx;
74
75 __om_query_builder(const char *p,string& r,const basic_openid_message& m)
76 : om(m), first(true), rv(r), pfx(p) {
77 for_each(om.fields_begin(),om.fields_end(),*this);
78 }
79 __om_query_builder(const char *p,string& r,const basic_openid_message& m,const string& u)
80 : om(m), first(true), rv(r), pfx(p) {
81 rv = u;
82 if(rv.find('?')==string::npos)
83 rv += '?';
84 else
85 first = false;
86 for_each(om.fields_begin(),om.fields_end(),*this);
87 }
88
89 result_type operator()(argument_type f) {
90 if(first)
91 first = false;
92 else
93 rv += '&';
94 if(pfx) rv += pfx;
95 rv+= f;
96 rv += '=';
97 rv += util::url_encode(om.get_field(f));
98 }
99 };
100
101 string basic_openid_message::append_query(const string& url,const char *pfx) const {
102 string rv;
103 return __om_query_builder(pfx,rv,*this,url).rv;
104 }
105 string basic_openid_message::query_string(const char *pfx) const {
106 string rv;
107 return __om_query_builder(pfx,rv,*this).rv;
108 }
109
110 void basic_openid_message::reset_fields() {
111 throw not_implemented(OPKELE_CP_ "reset_fields() not implemented");
112 }
113 void basic_openid_message::set_field(const string&,const string&) {
114 throw not_implemented(OPKELE_CP_ "set_field() not implemented");
115 }
116 void basic_openid_message::reset_field(const string&) {
117 throw not_implemented(OPKELE_CP_ "reset_field() not implemented");
118 }
119
120 void basic_openid_message::from_keyvalues(const string& kv) { 44 void basic_openid_message::from_keyvalues(const string& kv) {
121 reset_fields(); 45 reset_fields();
122 string::size_type p = 0; 46 string::size_type p = 0;
123 while(true) { 47 while(true) {
124 string::size_type co = kv.find(':',p); 48 string::size_type co = kv.find(':',p);
125 if(co==string::npos) 49 if(co==string::npos)
126 break; 50 break;
127#ifndef POSTELS_LAW 51#ifndef POSTELS_LAW
128 string::size_type nl = kv.find('\n',co+1); 52 string::size_type nl = kv.find('\n',co+1);
129 if(nl==string::npos) 53 if(nl==string::npos)
130 throw bad_input(OPKELE_CP_ "malformed input"); 54 throw bad_input(OPKELE_CP_ "malformed input");
131 if(nl>co) 55 if(nl>co)
132 insert(value_type(kv.substr(p,co-p),kv.substr(co+1,nl-co-1))); 56 set_field(kv.substr(p,co-p),kv.substr(co+1,nl-co-1));
133 p = nl+1; 57 p = nl+1;
134#else /* POSTELS_LAW */ 58#else /* POSTELS_LAW */
135 string::size_type lb = kv.find_first_of("\r\n",co+1); 59 string::size_type lb = kv.find_first_of("\r\n",co+1);
136 if(lb==string::npos) { 60 if(lb==string::npos) {
137 set_field(kv.substr(p,co-p),kv.substr(co+1)); 61 set_field(kv.substr(p,co-p),kv.substr(co+1));
138 break; 62 break;
139 } 63 }
140 if(lb>co) 64 if(lb>co)
141 set_field(kv.substr(p,co-p),kv.substr(co+1,lb-co-1)); 65 set_field(kv.substr(p,co-p),kv.substr(co+1,lb-co-1));
142 string::size_type nolb = kv.find_first_not_of("\r\n",lb); 66 string::size_type nolb = kv.find_first_not_of("\r\n",lb);
143 if(nolb==string::npos) 67 if(nolb==string::npos)
144 break; 68 break;
145 p = nolb; 69 p = nolb;
146#endif /* POSTELS_LAW */ 70#endif /* POSTELS_LAW */
147 } 71 }
148 } 72 }
149 73
150 struct __om_kv_outputter : public unary_function<const string&,void> { 74 struct __om_kv_outputter : public unary_function<const string&,void> {
151 public: 75 public:
152 const basic_openid_message& om; 76 const basic_openid_message& om;
153 ostream& os; 77 ostream& os;
154 78
155 __om_kv_outputter(const basic_openid_message& m,ostream& s) 79 __om_kv_outputter(const basic_openid_message& m,ostream& s)
156 : om(m), os(s) { } 80 : om(m), os(s) { }
157 81
158 result_type operator()(argument_type f) { 82 result_type operator()(argument_type f) {
159 os << f << ':' << om.get_field(f) << '\n'; 83 os << f << ':' << om.get_field(f) << '\n';
160 } 84 }
161 }; 85 };
162 86
163 void basic_openid_message::to_keyvalues(ostream& o) const { 87 void basic_openid_message::to_keyvalues(ostream& o) const {
164 for_each(fields_begin(),fields_end(),__om_kv_outputter(*this,o)); 88 for_each(fields_begin(),fields_end(),__om_kv_outputter(*this,o));
165 } 89 }
166 90
167 struct __om_html_outputter : public unary_function<const string&,void> { 91 struct __om_html_outputter : public unary_function<const string&,void> {
168 public: 92 public:
169 const basic_openid_message& om; 93 const basic_openid_message& om;
170 ostream& os; 94 ostream& os;
171 const char *pfx; 95 const char *pfx;
172 96
173 __om_html_outputter(const basic_openid_message& m,ostream& s,const char *p=0) 97 __om_html_outputter(const basic_openid_message& m,ostream& s,const char *p=0)
174 : om(m), os(s), pfx(p) { } 98 : om(m), os(s), pfx(p) { }
175 99
176 result_type operator()(argument_type f) { 100 result_type operator()(argument_type f) {
177 os << 101 os <<
178 "<input type=\"hidden\"" 102 "<input type=\"hidden\""
179 " name=\""; 103 " name=\"";
180 if(pfx) 104 if(pfx)
181 os << util::attr_escape(pfx); 105 os << util::attr_escape(pfx);
182 os << util::attr_escape(f) << "\"" 106 os << util::attr_escape(f) << "\""
183 " value=\"" << util::attr_escape(om.get_field(f)) << "\" />"; 107 " value=\"" << util::attr_escape(om.get_field(f)) << "\" />";
184 } 108 }
185 }; 109 };
186 110
187 void basic_openid_message::to_htmlhiddens(ostream& o,const char* pfx) const { 111 void basic_openid_message::to_htmlhiddens(ostream& o,const char* pfx) const {
188 for_each(fields_begin(),fields_end(),__om_html_outputter(*this,o,pfx)); 112 for_each(fields_begin(),fields_end(),__om_html_outputter(*this,o,pfx));
189 } 113 }
190 114
191 void basic_openid_message::add_to_signed(const string& fields) { 115 void basic_openid_message::add_to_signed(const string& fields) {
192 string::size_type fnc = fields.find_first_not_of(","); 116 string::size_type fnc = fields.find_first_not_of(",");
193 if(fnc==string::npos) 117 if(fnc==string::npos)
194 throw bad_input(OPKELE_CP_ "Trying to add nothing in particular to the list of signed fields"); 118 throw bad_input(OPKELE_CP_ "Trying to add nothing in particular to the list of signed fields");
195 string signeds; 119 string signeds;
196 try { 120 try {
197 signeds = get_field("signed"); 121 signeds = get_field("signed");
198 string::size_type lnc = signeds.find_last_not_of(","); 122 string::size_type lnc = signeds.find_last_not_of(",");
199 if(lnc==string::npos) 123 if(lnc==string::npos)
200 signeds.assign(fields,fnc,fields.size()-fnc); 124 signeds.assign(fields,fnc,fields.size()-fnc);
201 else{ 125 else{
202 string::size_type ss = signeds.size(); 126 string::size_type ss = signeds.size();
203 if(lnc==(ss-1)) { 127 if(lnc==(ss-1)) {
204 signeds+= ','; 128 signeds+= ',';
205 signeds.append(fields,fnc,fields.size()-fnc); 129 signeds.append(fields,fnc,fields.size()-fnc);
206 }else{ 130 }else{
207 if(lnc<(ss-2)) 131 if(lnc<(ss-2))
208 signeds.replace(lnc+2,ss-lnc-2, 132 signeds.replace(lnc+2,ss-lnc-2,
209 fields,fnc,fields.size()-fnc); 133 fields,fnc,fields.size()-fnc);
210 else 134 else
211 signeds.append(fields,fnc,fields.size()-fnc); 135 signeds.append(fields,fnc,fields.size()-fnc);
212 } 136 }
213 } 137 }
214 }catch(failed_lookup&) { 138 }catch(failed_lookup&) {
215 signeds.assign(fields,fnc,fields.size()-fnc); 139 signeds.assign(fields,fnc,fields.size()-fnc);
216 } 140 }
217 set_field("signed",signeds); 141 set_field("signed",signeds);
218 } 142 }
219 143
220 string basic_openid_message::find_ns(const string& uri,const char *pfx) const { 144 string basic_openid_message::find_ns(const string& uri,const char *pfx) const {
221 try { 145 try {
222 return get_ns(uri); 146 return get_ns(uri);
223 }catch(failed_lookup&) { 147 }catch(failed_lookup&) {
224 return pfx; 148 return pfx;
225 } 149 }
226 } 150 }
227 string basic_openid_message::allocate_ns(const string& uri,const char *pfx) { 151 string basic_openid_message::allocate_ns(const string& uri,const char *pfx) {
228 if(!has_field("ns")) 152 if(!has_field("ns"))
229 return pfx; 153 return pfx;
230 if(has_ns(uri)) 154 if(has_ns(uri))
231 throw bad_input(OPKELE_CP_ "OpenID message already contains namespace"); 155 throw bad_input(OPKELE_CP_ "OpenID message already contains namespace");
232 string rv = pfx; 156 string rv = pfx;
233 if(has_field("ns."+rv)) { 157 if(has_field("ns."+rv)) {
234 string::reference c=rv[rv.length()]; 158 string::reference c=rv[rv.length()];
235 for(c='a';c<='z' && has_field("ns."+rv);++c); 159 for(c='a';c<='z' && has_field("ns."+rv);++c);
236 if(c=='z') 160 if(c=='z')
237 throw exception(OPKELE_CP_ "Failed to allocate namespace"); 161 throw exception(OPKELE_CP_ "Failed to allocate namespace");
238 } 162 }
239 set_field("ns."+rv,uri); 163 set_field("ns."+rv,uri);
240 return rv; 164 return rv;
241 } 165 }
242 166
243 void openid_message_t::copy_to(basic_openid_message& x) const {
244 x.reset_fields();
245 for(const_iterator i=begin();i!=end();++i)
246 x.set_field(i->first,i->second);
247 }
248
249 bool openid_message_t::has_field(const string& n) const { 167 bool openid_message_t::has_field(const string& n) const {
250 return find(n)!=end(); 168 return find(n)!=end();
251 } 169 }
252 const string& openid_message_t::get_field(const string& n) const { 170 const string& openid_message_t::get_field(const string& n) const {
253 const_iterator i=find(n); 171 const_iterator i=find(n);
254 if(i==end()) 172 if(i==end())
255 throw failed_lookup(OPKELE_CP_ n+": no such field"); 173 throw failed_lookup(OPKELE_CP_ n+": no such field");
256 return i->second; 174 return i->second;
257 } 175 }
258 176
259 openid_message_t::fields_iterator openid_message_t::fields_begin() const { 177 openid_message_t::fields_iterator openid_message_t::fields_begin() const {
260 return util::map_keys_iterator<const_iterator,string,const string&,const string*>(begin(),end()); 178 return util::map_keys_iterator<const_iterator,string,const string&,const string*>(begin(),end());
261 } 179 }
262 openid_message_t::fields_iterator openid_message_t::fields_end() const { 180 openid_message_t::fields_iterator openid_message_t::fields_end() const {
263 return util::map_keys_iterator<const_iterator,string,const string&,const string*>(end(),end()); 181 return util::map_keys_iterator<const_iterator,string,const string&,const string*>(end(),end());
264 } 182 }
265 183
266 void openid_message_t::reset_fields() { 184 void openid_message_t::reset_fields() {
267 clear(); 185 clear();
268 } 186 }
269 void openid_message_t::set_field(const string& n,const string& v) { 187 void openid_message_t::set_field(const string& n,const string& v) {
270 (*this)[n]=v; 188 (*this)[n]=v;
271 } 189 }
272 void openid_message_t::reset_field(const string& n) { 190 void openid_message_t::reset_field(const string& n) {
273 erase(n); 191 erase(n);
274 } 192 }
275 193
276} 194}
diff --git a/libopkele.pc.in b/libopkele.pc.in
index 011f2fe..2720a6a 100644
--- a/libopkele.pc.in
+++ b/libopkele.pc.in
@@ -1,11 +1,11 @@
1prefix=@prefix@ 1prefix=@prefix@
2exec_prefix=@exec_prefix@ 2exec_prefix=@exec_prefix@
3libdir=@libdir@ 3libdir=@libdir@
4includedir=@includedir@ 4includedir=@includedir@
5 5
6Name: libopkele 6Name: libopkele
7Description: C++ implementation of OpenID protocol 7Description: C++ implementation of OpenID protocol
8Version: @VERSION@ 8Version: @VERSION@
9Requires: openssl libpcre @KONFORKA_KONFORKA@ 9Requires: openssl libpcre @KONFORKA_KONFORKA@ @UUID_UUID@
10Cflags: -I${includedir} @LIBCURL_CPPFLAGS@ @PCRE_CFLAGS@ @EXPAT_CFLAGS@ @TIDY_CFLAGS@ 10Cflags: -I${includedir} @LIBCURL_CPPFLAGS@ @PCRE_CFLAGS@ @EXPAT_CFLAGS@ @TIDY_CFLAGS@
11Libs: -L${libdir} -lopkele @LIBCURL@ @PCRE_LIBS@ @EXPAT_LIBS@ @TIDY_LIBS@ 11Libs: -L${libdir} -lopkele @LIBCURL@ @PCRE_LIBS@ @EXPAT_LIBS@ @TIDY_LIBS@