Mercurial > openid
comparison src/c/openid.c @ 3:f59083771ee2
Saving associations
author | Adam Chlipala <adam@chlipala.net> |
---|---|
date | Sun, 26 Dec 2010 15:11:23 -0500 |
parents | b757dc2bd2f6 |
children | 2d409aff8800 |
comparison
equal
deleted
inserted
replaced
2:b757dc2bd2f6 | 3:f59083771ee2 |
---|---|
3 #include <openssl/sha.h> | 3 #include <openssl/sha.h> |
4 #include <curl/curl.h> | 4 #include <curl/curl.h> |
5 #include <expat.h> | 5 #include <expat.h> |
6 | 6 |
7 #include <openid.h> | 7 #include <openid.h> |
8 | |
9 #define BUF_MAX 10240 | |
10 #define BUF_INIT 1024 | |
8 | 11 |
9 struct uw_OpenidFfi_discovery { | 12 struct uw_OpenidFfi_discovery { |
10 uw_Basis_string endpoint, localId; | 13 uw_Basis_string endpoint, localId; |
11 }; | 14 }; |
12 | 15 |
70 } | 73 } |
71 | 74 |
72 typedef struct { | 75 typedef struct { |
73 XML_Parser parser; | 76 XML_Parser parser; |
74 int any_errors; | 77 int any_errors; |
75 } curl_data; | 78 } curl_discovery_data; |
76 | 79 |
77 static size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp) { | 80 static size_t write_discovery_data(void *buffer, size_t size, size_t nmemb, void *userp) { |
78 curl_data *d = userp; | 81 curl_discovery_data *d = userp; |
79 | 82 |
80 if (!XML_Parse(d->parser, buffer, size * nmemb, 0)) | 83 if (!XML_Parse(d->parser, buffer, size * nmemb, 0)) |
81 d->any_errors = 1; | 84 d->any_errors = 1; |
82 | 85 |
83 return size * nmemb; | 86 return size * nmemb; |
84 } | 87 } |
85 | 88 |
86 uw_OpenidFfi_discovery *uw_OpenidFfi_discover(uw_context ctx, uw_Basis_string id) { | 89 uw_OpenidFfi_discovery *uw_OpenidFfi_discover(uw_context ctx, uw_Basis_string id) { |
87 char *s; | 90 char *s; |
88 CURL *c = curl(ctx); | 91 CURL *c = curl(ctx); |
89 curl_data cd = {}; | 92 curl_discovery_data cd = {}; |
90 uw_OpenidFfi_discovery dy = uw_malloc(ctx, sizeof(struct uw_OpenidFfi_discovery)); | 93 uw_OpenidFfi_discovery dy = uw_malloc(ctx, sizeof(struct uw_OpenidFfi_discovery)); |
91 endpoint ep = {ctx, dy}; | 94 endpoint ep = {ctx, dy}; |
92 CURLcode code; | 95 CURLcode code; |
93 | 96 |
94 dy->endpoint = dy->localId = NULL; | 97 dy->endpoint = dy->localId = NULL; |
108 XML_SetUserData(cd.parser, &ep); | 111 XML_SetUserData(cd.parser, &ep); |
109 uw_push_cleanup(ctx, (void (*)(void *))XML_ParserFree, cd.parser); | 112 uw_push_cleanup(ctx, (void (*)(void *))XML_ParserFree, cd.parser); |
110 XML_SetElementHandler(cd.parser, startElement, endElement); | 113 XML_SetElementHandler(cd.parser, startElement, endElement); |
111 | 114 |
112 curl_easy_setopt(c, CURLOPT_URL, id); | 115 curl_easy_setopt(c, CURLOPT_URL, id); |
113 curl_easy_setopt(c, CURLOPT_WRITEFUNCTION, write_data); | 116 curl_easy_setopt(c, CURLOPT_WRITEFUNCTION, write_discovery_data); |
114 curl_easy_setopt(c, CURLOPT_WRITEDATA, &cd); | 117 curl_easy_setopt(c, CURLOPT_WRITEDATA, &cd); |
115 | 118 |
116 code = curl_easy_perform(c); | 119 code = curl_easy_perform(c); |
117 uw_pop_cleanup(ctx); | 120 uw_pop_cleanup(ctx); |
118 | 121 |
122 uw_OpenidFfi_discovery *dyp = malloc(sizeof(uw_OpenidFfi_discovery)); | 125 uw_OpenidFfi_discovery *dyp = malloc(sizeof(uw_OpenidFfi_discovery)); |
123 *dyp = ep.d; | 126 *dyp = ep.d; |
124 return dyp; | 127 return dyp; |
125 } | 128 } |
126 } | 129 } |
130 | |
131 uw_OpenidFfi_inputs uw_OpenidFfi_createInputs(uw_context ctx) { | |
132 uw_buffer *r = uw_malloc(ctx, sizeof(uw_buffer)); | |
133 uw_buffer_init(BUF_MAX, r, BUF_INIT); | |
134 return r; | |
135 } | |
136 | |
137 static int okForPost(const char *s) { | |
138 for (; *s; ++s) | |
139 if (*s == '=' || *s == '&') | |
140 return 0; | |
141 return 1; | |
142 } | |
143 | |
144 uw_unit uw_OpenidFfi_addInput(uw_context ctx, uw_OpenidFfi_inputs buf, uw_Basis_string key, uw_Basis_string value) { | |
145 if (!okForPost(key)) | |
146 uw_error(ctx, FATAL, "Invalid key for OpenID inputs"); | |
147 if (!okForPost(value)) | |
148 uw_error(ctx, FATAL, "Invalid value for OpenID inputs"); | |
149 | |
150 if (uw_buffer_used(buf) > 0) | |
151 uw_buffer_append(buf, "&", 1); | |
152 | |
153 uw_buffer_append(buf, key, strlen(key)); | |
154 uw_buffer_append(buf, "=", 1); | |
155 uw_buffer_append(buf, value, strlen(value)); | |
156 | |
157 return uw_unit_v; | |
158 } | |
159 | |
160 uw_Basis_string uw_OpenidFfi_getOutput(uw_context ctx, uw_OpenidFfi_outputs buf, uw_Basis_string key) { | |
161 char *s = buf->start; | |
162 | |
163 for (; *s; s = strchr(strchr(s, 0)+1, 0)+1) | |
164 if (!strcmp(key, s)) | |
165 return strchr(s, 0)+1; | |
166 | |
167 return NULL; | |
168 } | |
169 | |
170 static size_t write_buffer_data(void *buffer, size_t size, size_t nmemb, void *userp) { | |
171 uw_buffer *buf = userp; | |
172 | |
173 uw_buffer_append(buf, buffer, size * nmemb); | |
174 | |
175 return size * nmemb; | |
176 } | |
177 | |
178 const char curl_failure[] = "error\0Error fetching URL"; | |
179 | |
180 uw_OpenidFfi_outputs uw_OpenidFfi_indirect(uw_context ctx, uw_Basis_string url, uw_OpenidFfi_inputs inps) { | |
181 uw_buffer *buf = uw_malloc(ctx, sizeof(uw_buffer)); | |
182 CURL *c = curl(ctx); | |
183 CURLcode code; | |
184 | |
185 uw_buffer_init(BUF_MAX, buf, BUF_INIT); | |
186 | |
187 uw_buffer_append(inps, "", 1); | |
188 | |
189 curl_easy_setopt(c, CURLOPT_URL, url); | |
190 curl_easy_setopt(c, CURLOPT_POSTFIELDS, inps->start); | |
191 curl_easy_setopt(c, CURLOPT_WRITEFUNCTION, write_buffer_data); | |
192 curl_easy_setopt(c, CURLOPT_WRITEDATA, buf); | |
193 | |
194 code = curl_easy_perform(c); | |
195 | |
196 uw_buffer_append(buf, "", 1); | |
197 | |
198 if (code) { | |
199 uw_buffer_reset(buf); | |
200 uw_buffer_append(buf, curl_failure, sizeof curl_failure); | |
201 } else { | |
202 char *s; | |
203 | |
204 s = buf->start; | |
205 while (*s) { | |
206 char *colon = strchr(s, ':'), *newline; | |
207 | |
208 if (!colon) { | |
209 *s = 0; | |
210 break; | |
211 } | |
212 | |
213 newline = strchr(colon+1, '\n'); | |
214 | |
215 if (!newline) { | |
216 *s = 0; | |
217 break; | |
218 } | |
219 | |
220 *colon = 0; | |
221 *newline = 0; | |
222 s = newline+1; | |
223 } | |
224 } | |
225 | |
226 return buf; | |
227 } |