summaryrefslogtreecommitdiff
path: root/src/identity-provider
diff options
context:
space:
mode:
authorPhil <phil.buschmann@tum.de>2018-01-09 14:29:29 +0100
committerPhil <phil.buschmann@tum.de>2018-01-09 14:29:29 +0100
commitf0a84723fae7454cdefbc1c0125da71732c5242d (patch)
treeb6c218a84ccdea5339a36fd2510971a85f11c603 /src/identity-provider
parentf2d31fb82a314dcf6819dd494ff4a11e4f871c4e (diff)
downloadgnunet-f0a84723fae7454cdefbc1c0125da71732c5242d.tar.gz
gnunet-f0a84723fae7454cdefbc1c0125da71732c5242d.zip
-wip post authentication
Diffstat (limited to 'src/identity-provider')
-rw-r--r--src/identity-provider/logfile.txt73
-rw-r--r--src/identity-provider/plugin_rest_identity_provider.c459
2 files changed, 415 insertions, 117 deletions
diff --git a/src/identity-provider/logfile.txt b/src/identity-provider/logfile.txt
deleted file mode 100644
index a59f2478a..000000000
--- a/src/identity-provider/logfile.txt
+++ /dev/null
@@ -1,73 +0,0 @@
1*** Error in `/usr/local/lib//gnunet/libexec/gnunet-rest-server': free(): invalid pointer: 0x00007f9c415c9275 ***
2*** Error in `/usr/local/lib//gnunet/libexec/gnunet-rest-server': free(): invalid pointer: 0x00007f0888c25275 ***
3*** Error in `/usr/local/lib//gnunet/libexec/gnunet-rest-server': free(): invalid pointer: 0x00007f7dee65b275 ***
4Nov 23 13:58:28-246065 gnunet-rest-server-26879 ERROR Error: (null)
5Nov 23 13:58:46-677968 gnunet-rest-server-26879 ERROR Error: Missing openid scope
6Nov 23 13:59:34-165447 gnunet-rest-server-26901 ERROR Error: Missing openid scope
7Nov 23 14:04:07-545573 gnunet-rest-server-28097 ERROR Error: Response type is not code
8Nov 23 14:53:06-102430 gnunet-rest-server-30299 ERROR Error: Missing openid scope
9Nov 23 14:54:04-248567 gnunet-rest-server-30798 ERROR Error: Missing openid scope
10Nov 23 14:56:12-809322 gnunet-rest-server-31914 ERROR Error: Missing openid scope
11Nov 23 14:56:39-819194 gnunet-rest-server-31914 ERROR Error: Missing openid scope
12Nov 23 14:58:38-889573 gnunet-rest-server-601 ERROR Error: Missing openid scope
13Nov 30 11:59:42-727619 gnunet-rest-server-9307 ERROR (null)Nov 30 12:00:28-889186 gnunet-rest-server-9307 ERROR (null)Nov 30 12:01:56-950658 gnunet-rest-server-10445 ERROR con_handle: /idp/authorize
14Nov 30 12:01:56-982304 gnunet-rest-server-10445 ERROR url: /idp/authorize
15Nov 30 12:08:22-749785 gnunet-rest-server-11652 ERROR con_handle: /idp/authorize
16Nov 30 12:08:22-782042 gnunet-rest-server-11652 ERROR url: /idp/authorize
17Nov 30 12:39:51-816632 gnunet-rest-server-14500 ERROR url: /idp/authorize
18Dec 04 09:51:02-313753 gnunet-rest-server-1974 ERROR No default ego configured in identity service
19Dec 04 09:51:09-311601 gnunet-rest-server-1974 ERROR No default ego configured in identity service
20Failed to send data in request for `/idp/attributes/testego'.
21Dec 04 11:58:11-490711 gnunet-rest-server-6760 ERROR MHD encountered error handling request: 1
22Failed to send data in request for `/idp/tickets/testego'.
23Dec 04 11:58:11-508689 gnunet-rest-server-6760 ERROR MHD encountered error handling request: 1
24Failed to send data in request for `/names/'.
25Dec 04 11:58:11-511015 gnunet-rest-server-6760 ERROR MHD encountered error handling request: 1
26Failed to send data in request for `/idp/tickets/testego'.
27Dec 04 12:38:15-960444 gnunet-rest-server-6760 ERROR MHD encountered error handling request: 1
28Failed to send data in request for `/names/'.
29Dec 04 12:38:16-003695 gnunet-rest-server-6760 ERROR MHD encountered error handling request: 1
30Failed to send data in request for `/idp/attributes/testego'.
31Dec 04 12:38:16-021887 gnunet-rest-server-6760 ERROR MHD encountered error handling request: 1
32Failed to send data in request for `/idp/tickets/testego'.
33Dec 04 12:38:29-977580 gnunet-rest-server-6760 ERROR MHD encountered error handling request: 1
34Failed to send data in request for `/names/'.
35Dec 04 12:38:30-008002 gnunet-rest-server-6760 ERROR MHD encountered error handling request: 1
36Failed to send data in request for `/idp/attributes/testego'.
37Dec 04 12:38:30-036167 gnunet-rest-server-6760 ERROR MHD encountered error handling request: 1
38Failed to send data in request for `/idp/attributes/testego'.
39Dec 04 12:43:23-654462 gnunet-rest-server-6760 ERROR MHD encountered error handling request: 1
40Failed to send data in request for `/idp/tickets/testego'.
41Dec 04 12:43:23-655070 gnunet-rest-server-6760 ERROR MHD encountered error handling request: 1
42Failed to send data in request for `/names/'.
43Dec 04 12:43:23-665165 gnunet-rest-server-6760 ERROR MHD encountered error handling request: 1
44Failed to send data in request for `/idp/tickets/testego'.
45Dec 04 13:06:56-306701 gnunet-rest-server-9599 ERROR MHD encountered error handling request: 1
46Failed to send data in request for `/idp/attributes/testego'.
47Dec 04 13:06:56-326200 gnunet-rest-server-9599 ERROR MHD encountered error handling request: 1
48Failed to send data in request for `/names/'.
49Dec 04 13:06:56-331741 gnunet-rest-server-9599 ERROR MHD encountered error handling request: 1
50Dec 04 13:09:56-080335 gnunet-rest-server-10794 ERROR URL (response_type=code)
51Dec 04 13:12:49-565164 gnunet-rest-server-11931 ERROR URL (response_type=code)
52Failed to send data in request for `/idp/tickets/testego'.
53Dec 04 13:12:49-586734 gnunet-rest-server-11931 ERROR MHD encountered error handling request: 1
54Failed to send data in request for `/idp/attributes/testego'.
55Dec 04 13:12:49-592627 gnunet-rest-server-11931 ERROR MHD encountered error handling request: 1
56Failed to send data in request for `/names/'.
57Dec 04 13:12:49-601007 gnunet-rest-server-11931 ERROR MHD encountered error handling request: 1
58Dec 04 13:15:25-370395 gnunet-rest-server-13261 ERROR URL (acr_values=true)
59Failed to send data in request for `/idp/tickets/testego'.
60Dec 04 13:15:25-395382 gnunet-rest-server-13261 ERROR MHD encountered error handling request: 1
61Failed to send data in request for `/idp/attributes/testego'.
62Dec 04 13:15:25-399622 gnunet-rest-server-13261 ERROR MHD encountered error handling request: 1
63Failed to send data in request for `/names/'.
64Dec 04 13:15:25-408151 gnunet-rest-server-13261 ERROR MHD encountered error handling request: 1
65Dec 04 13:36:24-427812 gnunet-rest-server-15336 ERROR URL (?response_type=code&client_id=test&scope=openid email&redirect_uri=https://google.com&nonce=11111&ui_locales=test&)
66Failed to send data in request for `/idp/tickets/testego'.
67Dec 04 13:36:24-450636 gnunet-rest-server-15336 ERROR MHD encountered error handling request: 1
68Failed to send data in request for `/idp/attributes/testego'.
69Dec 04 13:36:24-456164 gnunet-rest-server-15336 ERROR MHD encountered error handling request: 1
70Failed to send data in request for `/names/'.
71Dec 04 13:36:24-461431 gnunet-rest-server-15336 ERROR MHD encountered error handling request: 1
72Dec 04 13:39:02-052691 gnunet-rest-server-16482 ERROR URL (?response_type=code&client_id=test&scope=openid email&redirect_uri=https://google.com&nonce=1111&ui_locales=test&acr_values=true)
73Dec 04 15:27:43-226881 gnunet-rest-server-16482 ERROR URL (?response_type=code&client_id=test&scope=openid email&redirect_uri=https://google.com&nonce=11111&ui_locales=test&acr_values=true)
diff --git a/src/identity-provider/plugin_rest_identity_provider.c b/src/identity-provider/plugin_rest_identity_provider.c
index 1aa1f818d..9d61ac92b 100644
--- a/src/identity-provider/plugin_rest_identity_provider.c
+++ b/src/identity-provider/plugin_rest_identity_provider.c
@@ -150,8 +150,6 @@
150 * OIDC expected scope part while authorizing 150 * OIDC expected scope part while authorizing
151 */ 151 */
152#define OIDC_EXPECTED_AUTHORIZATION_SCOPE "openid" 152#define OIDC_EXPECTED_AUTHORIZATION_SCOPE "openid"
153
154
155/** 153/**
156 * OIDC ignored parameter array 154 * OIDC ignored parameter array
157 */ 155 */
@@ -167,6 +165,8 @@ char* OIDC_ignored_parameter_array [] =
167 "acr_values" 165 "acr_values"
168}; 166};
169 167
168struct GNUNET_NAMESTORE_Handle *namestore_handle;
169
170/** 170/**
171 * OIDC authorized identities and times hashmap 171 * OIDC authorized identities and times hashmap
172 */ 172 */
@@ -366,6 +366,10 @@ cleanup_handle (struct RequestHandle *handle)
366 GNUNET_free (handle->url); 366 GNUNET_free (handle->url);
367 if (NULL != handle->emsg) 367 if (NULL != handle->emsg)
368 GNUNET_free (handle->emsg); 368 GNUNET_free (handle->emsg);
369 if (NULL != handle->edesc)
370 GNUNET_free (handle->edesc);
371 if (NULL != handle->eredirect)
372 GNUNET_free (handle->eredirect);
369 for (ego_entry = handle->ego_head; 373 for (ego_entry = handle->ego_head;
370 NULL != ego_entry;) 374 NULL != ego_entry;)
371 { 375 {
@@ -1125,32 +1129,358 @@ options_cont (struct GNUNET_REST_RequestHandle *con_handle,
1125} 1129}
1126 1130
1127/** 1131/**
1128 * Respond to OPTIONS request 1132 * Function called if we had an error in zone-to-name mapping.
1133 */
1134static void
1135zone_to_name_error (void *cls)
1136{
1137 struct RequestHandle *handle = cls;
1138
1139 handle->emsg = GNUNET_strdup("unauthorized_client");
1140 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1141
1142 GNUNET_NAMESTORE_disconnect (namestore_handle);
1143 namestore_handle = NULL;
1144 GNUNET_SCHEDULER_add_now (&do_error, handle);
1145}
1146
1147/**
1148 * Test if a name mapping was found, if so, continue, else, throw error
1149 *
1150 * @param cls closure
1151 * @param zone_key public key of the zone
1152 * @param name name that is being mapped (at most 255 characters long)
1153 * @param rd_count number of entries in @a rd array
1154 * @param rd array of records with data to store
1155 */
1156static void
1157zone_to_name_cb (void *cls,
1158 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
1159 const char *name,
1160 unsigned int rd_count,
1161 const struct GNUNET_GNSRECORD_Data *rd)
1162{
1163 struct RequestHandle *handle = cls;
1164
1165
1166 if (0 == rd_count)
1167 {
1168 handle->emsg = GNUNET_strdup("unauthorized_client");
1169 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1170
1171 GNUNET_NAMESTORE_disconnect (namestore_handle);
1172 namestore_handle = NULL;
1173 GNUNET_SCHEDULER_add_now (&do_error, handle);
1174 return;
1175 }
1176}
1177
1178/**
1179 * Respond to authorization request
1129 * 1180 *
1130 * @param con_handle the connection handle 1181 * @param con_handle the connection handle
1131 * @param url the url 1182 * @param url the url
1132 * @param cls the RequestHandle 1183 * @param cls the RequestHandle
1133 */ 1184 */
1134static void 1185static void
1135authorize_cont (struct GNUNET_REST_RequestHandle *con_handle, 1186authorize_get_cont (struct GNUNET_REST_RequestHandle *con_handle,
1136 const char* url, 1187 const char* url,
1137 void *cls) 1188 void *cls)
1138{ 1189{
1190 /** The Authorization Server MUST validate all the OAuth 2.0 parameters
1191 * according to the OAuth 2.0 specification.
1192 */
1193 /**
1194 * If the sub (subject) Claim is requested with a specific value for the
1195 * ID Token, the Authorization Server MUST only send a positive response
1196 * if the End-User identified by that sub value has an active session with
1197 * the Authorization Server or has been Authenticated as a result of the
1198 * request. The Authorization Server MUST NOT reply with an ID Token or
1199 * Access Token for a different user, even if they have an active session
1200 * with the Authorization Server. Such a request can be made either using
1201 * an id_token_hint parameter or by requesting a specific Claim Value as
1202 * described in Section 5.5.1, if the claims parameter is supported by
1203 * the implementation.
1204 */
1205
1139 struct MHD_Response *resp; 1206 struct MHD_Response *resp;
1140 struct RequestHandle *handle = cls; 1207 struct RequestHandle *handle = cls;
1141 char *response_type; 1208 char *response_type;
1142 char *client_id; 1209 char *client_id;
1143 char *scope; 1210 char *scope;
1144 char *redirect_uri; 1211 char *redirect_uri;
1212 char *expected_redirect_uri;
1145 char *state = NULL; 1213 char *state = NULL;
1146 char *nonce = NULL; 1214 char *nonce = NULL;
1147 struct GNUNET_TIME_Absolute current_time, *relog_time; 1215 struct GNUNET_TIME_Absolute current_time, *relog_time;
1148 char *login_base_url, *new_redirect; 1216 char *login_base_url, *new_redirect;
1149 struct GNUNET_HashCode cache_key; 1217 struct GNUNET_HashCode cache_key;
1218 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_pkey;
1219 struct GNUNET_CRYPTO_EcdsaPublicKey pubkey;
1220 int number_of_ignored_parameter, iterator;
1221
1222 // REQUIRED value: client_id
1223 GNUNET_CRYPTO_hash (OIDC_CLIENT_ID_KEY, strlen (OIDC_CLIENT_ID_KEY),
1224 &cache_key);
1225 if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle->url_param_map,
1226 &cache_key))
1227 {
1228 handle->emsg=GNUNET_strdup("invalid_request");
1229 handle->edesc=GNUNET_strdup("Missing parameter: client_id");
1230 GNUNET_SCHEDULER_add_now (&do_error, handle);
1231 return;
1232 }
1233 client_id = GNUNET_CONTAINER_multihashmap_get(handle->rest_handle->url_param_map,
1234 &cache_key);
1235 if ( GNUNET_OK
1236 != GNUNET_CRYPTO_ecdsa_public_key_from_string (client_id,
1237 strlen (client_id),
1238 &pubkey) )
1239 {
1240 handle->emsg=GNUNET_strdup("unauthorized_client");
1241 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1242 GNUNET_SCHEDULER_add_now (&do_error, handle);
1243 }
1244
1245 // Checks if client_id is valid:
1246 namestore_handle = GNUNET_NAMESTORE_connect(cfg);
1247 zone_pkey = GNUNET_IDENTITY_ego_get_private_key (handle->ego_entry->ego);
1248 GNUNET_NAMESTORE_zone_to_name (namestore_handle, zone_pkey, &pubkey,
1249 zone_to_name_error, handle, zone_to_name_cb,
1250 handle);
1251
1252 // REQUIRED value: redirect_uri
1253 GNUNET_CRYPTO_hash (OIDC_REDIRECT_URI_KEY, strlen (OIDC_REDIRECT_URI_KEY),
1254 &cache_key);
1255 if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle->url_param_map,
1256 &cache_key))
1257 {
1258 handle->emsg=GNUNET_strdup("invalid_request");
1259 handle->edesc=GNUNET_strdup("Missing parameter: redirect_uri");
1260 GNUNET_SCHEDULER_add_now (&do_error, handle);
1261 return;
1262 }
1263 redirect_uri = GNUNET_CONTAINER_multihashmap_get(handle->rest_handle->url_param_map,
1264 &cache_key);
1265
1266 GNUNET_asprintf (&expected_redirect_uri, "https://%s.zkey", client_id);
1267
1268 // verify the redirect uri matches https://<client_id>.zkey[/xyz]
1269 if( 0 != strncmp( expected_redirect_uri, redirect_uri, strlen(expected_redirect_uri)) )
1270 {
1271 handle->emsg=GNUNET_strdup("invalid_request");
1272 handle->edesc=GNUNET_strdup("Invalid redirect_uri");
1273 GNUNET_free(expected_redirect_uri);
1274 GNUNET_SCHEDULER_add_now (&do_error, handle);
1275 return;
1276 }
1277 handle->eredirect = GNUNET_strdup(redirect_uri);
1278
1279 // REQUIRED value: response_type
1280 GNUNET_CRYPTO_hash (OIDC_RESPONSE_TYPE_KEY, strlen (OIDC_RESPONSE_TYPE_KEY),
1281 &cache_key);
1282 if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle->url_param_map,
1283 &cache_key))
1284 {
1285 handle->emsg=GNUNET_strdup("invalid_request");
1286 handle->edesc=GNUNET_strdup("Missing parameter: response_type");
1287 GNUNET_SCHEDULER_add_now (&do_redirect_error, handle);
1288 return;
1289 }
1290 response_type = GNUNET_CONTAINER_multihashmap_get(handle->rest_handle->url_param_map,
1291 &cache_key);
1292
1293 // REQUIRED value: scope
1294 GNUNET_CRYPTO_hash (OIDC_SCOPE_KEY, strlen (OIDC_SCOPE_KEY), &cache_key);
1295 if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle->url_param_map,
1296 &cache_key))
1297 {
1298 handle->emsg=GNUNET_strdup("invalid_request");
1299 handle->edesc=GNUNET_strdup("Missing parameter: scope");
1300 GNUNET_SCHEDULER_add_now (&do_redirect_error, handle);
1301 return;
1302 }
1303 scope = GNUNET_CONTAINER_multihashmap_get(handle->rest_handle->url_param_map,
1304 &cache_key);
1305
1306 //RECOMMENDED value: state
1307 GNUNET_CRYPTO_hash (OIDC_STATE_KEY, strlen (OIDC_STATE_KEY), &cache_key);
1308 if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle->url_param_map,
1309 &cache_key))
1310 {
1311 state = GNUNET_CONTAINER_multihashmap_get(handle->rest_handle->url_param_map,
1312 &cache_key);
1313 }
1314
1315 //OPTIONAL value: nonce
1316 GNUNET_CRYPTO_hash (OIDC_NONCE_KEY, strlen (OIDC_NONCE_KEY), &cache_key);
1317 if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle->url_param_map,
1318 &cache_key))
1319 {
1320 nonce = GNUNET_CONTAINER_multihashmap_get(handle->rest_handle->url_param_map,
1321 &cache_key);
1322 }
1323
1324 number_of_ignored_parameter = sizeof(OIDC_ignored_parameter_array) / sizeof(char *);
1325 for( iterator = 0; iterator < number_of_ignored_parameter; iterator++ )
1326 {
1327 GNUNET_CRYPTO_hash (OIDC_ignored_parameter_array[iterator],
1328 strlen(OIDC_ignored_parameter_array[iterator]),
1329 &cache_key);
1330 if(GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains(handle->rest_handle->url_param_map,
1331 &cache_key))
1332 {
1333 handle->emsg=GNUNET_strdup("access_denied");
1334 GNUNET_asprintf (*handle->edesc, "Server will not handle parameter: %s",
1335 OIDC_ignored_parameter_array[iterator]);
1336 GNUNET_SCHEDULER_add_now (&do_redirect_error, handle);
1337 return;
1338 }
1339 }
1340
1341 // Checks if response_type is 'code'
1342 if( 0 != strcmp( response_type, OIDC_EXPECTED_AUTHORIZATION_RESPONSE_TYPE ) )
1343 {
1344 handle->emsg=GNUNET_strdup("unsupported_response_type");
1345 handle->edesc=GNUNET_strdup("The authorization server does not support "
1346 "obtaining this authorization code.");
1347 GNUNET_SCHEDULER_add_now (&do_redirect_error, handle);
1348 return;
1349 }
1350 // Checks if scope contains 'openid'
1351 if( NULL == strstr( scope, OIDC_EXPECTED_AUTHORIZATION_SCOPE ) )
1352 {
1353 handle->emsg=GNUNET_strdup("invalid_scope");
1354 handle->edesc=GNUNET_strdup("The requested scope is invalid, unknown, or "
1355 "malformed.");
1356 GNUNET_SCHEDULER_add_now (&do_redirect_error, handle);
1357 return;
1358 }
1359
1360 //TODO check other values and use them accordingly
1361
1362 GNUNET_CRYPTO_hash (OIDC_COOKIE_HEADER_KEY, strlen (OIDC_COOKIE_HEADER_KEY),
1363 &cache_key);
1364 //No identity-cookie -> redirect to login
1365 if ( GNUNET_YES
1366 == GNUNET_CONTAINER_multihashmap_contains (con_handle->header_param_map,
1367 &cache_key) )
1368 {
1369 //split cookies and find 'Identity' cookie
1370 char* cookies = GNUNET_CONTAINER_multihashmap_get (
1371 con_handle->header_param_map, &cache_key);
1372 char delimiter[] = "; ";
1373 char *identity_cookie;
1374 identity_cookie = strtok(cookies, delimiter);
1375
1376 while ( NULL != identity_cookie )
1377 {
1378 if ( NULL != strstr (identity_cookie, OIDC_COOKIE_HEADER_INFORMATION_KEY) )
1379 {
1380 break;
1381 }
1382 identity_cookie = strtok (NULL, delimiter);
1383 }
1384 GNUNET_CRYPTO_hash (identity_cookie, strlen (identity_cookie), &cache_key);
1150 1385
1151 //TODO clean up method 1386 //No login time for identity -> redirect to login
1387 if ( GNUNET_YES
1388 == GNUNET_CONTAINER_multihashmap_contains (OIDC_authorized_identities,
1389 &cache_key) )
1390 {
1391 relog_time = GNUNET_CONTAINER_multihashmap_get (
1392 OIDC_authorized_identities, &cache_key);
1152 1393
1153 /** The Authorization Server MUST validate all the OAuth 2.0 parameters 1394 current_time = GNUNET_TIME_absolute_get();
1395
1396 GNUNET_CONTAINER_multihashmap_remove_all(OIDC_authorized_identities, &cache_key);
1397 // 30 min after old login -> redirect to login
1398 if ( current_time.abs_value_us <= relog_time->abs_value_us )
1399 {
1400 resp = GNUNET_REST_create_response ("");
1401
1402 GNUNET_CRYPTO_ecdsa_public_key_from_string (identity_cookie,
1403 strlen (identity_cookie),
1404 &pubkey);
1405
1406 // iterate over egos and compare their public key
1407// GNUNET_IDENTITY_PROVIDER_get_attributes_start
1408 // iterate over scope variables
1409 char delimiter[] = " ";
1410 char *scope_attribute;
1411 scope_attribute = strtok(scope, delimiter);
1412
1413 while ( NULL != scope_attribute )
1414 {
1415 if ( NULL == strstr (scope_attribute, OIDC_EXPECTED_AUTHORIZATION_SCOPE) )
1416 {
1417 // claim attribute from ego
1418 scope_attribute = strtok (NULL, delimiter);
1419 }
1420 }
1421 // create an authorization code
1422
1423// GNUNET_IDENTITY_PROVIDER_t
1424
1425 MHD_add_response_header (resp, "Location", redirect_uri);
1426 handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND);
1427 cleanup_handle (handle);
1428 GNUNET_free(relog_time);
1429 return;
1430 }
1431 GNUNET_free(relog_time);
1432 }
1433 }
1434
1435
1436 // login redirection
1437 if ( GNUNET_OK
1438 == GNUNET_CONFIGURATION_get_value_string (cfg, "identity-rest-plugin",
1439 "address", &login_base_url) )
1440 {
1441 GNUNET_asprintf (&new_redirect, "%s?%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s",
1442 login_base_url,
1443 OIDC_RESPONSE_TYPE_KEY,
1444 response_type,
1445 OIDC_CLIENT_ID_KEY,
1446 client_id,
1447 OIDC_REDIRECT_URI_KEY,
1448 redirect_uri,
1449 OIDC_SCOPE_KEY,
1450 scope,
1451 OIDC_STATE_KEY,
1452 (NULL == state) ? state : "",
1453 OIDC_NONCE_KEY,
1454 (NULL == nonce) ? nonce : "");
1455 resp = GNUNET_REST_create_response ("");
1456 MHD_add_response_header (resp, "Location", new_redirect);
1457 }
1458 else
1459 {
1460 handle->emsg = GNUNET_strdup("No server configuration");
1461 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1462 GNUNET_SCHEDULER_add_now (&do_error, handle);
1463 return;
1464 }
1465 handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND);
1466 cleanup_handle (handle);
1467 GNUNET_free(new_redirect);
1468 return;
1469}
1470
1471/**
1472 * Respond to authorization request
1473 *
1474 * @param con_handle the connection handle
1475 * @param url the url
1476 * @param cls the RequestHandle
1477 */
1478static void
1479authorize_post_cont (struct GNUNET_REST_RequestHandle *con_handle,
1480 const char* url,
1481 void *cls)
1482{
1483 /** The Authorization Server MUST validate all the OAuth 2.0 parameters
1154 * according to the OAuth 2.0 specification. 1484 * according to the OAuth 2.0 specification.
1155 */ 1485 */
1156 /** 1486 /**
@@ -1166,7 +1496,27 @@ authorize_cont (struct GNUNET_REST_RequestHandle *con_handle,
1166 * the implementation. 1496 * the implementation.
1167 */ 1497 */
1168 1498
1499 struct MHD_Response *resp;
1500 struct RequestHandle *handle = cls;
1501 char *response_type;
1502 char *client_id;
1503 char *scope;
1504 char *redirect_uri;
1505 char *expected_redirect_uri;
1506 char *state = NULL;
1507 char *nonce = NULL;
1508 struct GNUNET_TIME_Absolute current_time, *relog_time;
1509 char *login_base_url, *new_redirect;
1510 struct GNUNET_HashCode cache_key;
1511 const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_pkey;
1512 struct GNUNET_CRYPTO_EcdsaPublicKey pubkey;
1513 int number_of_ignored_parameter, iterator;
1169 1514
1515 json_t *root;
1516 json_error_t error;
1517 json_t *identity;
1518 root = json_loads (handle->rest_handle->data, 0, &error);
1519 client_id = json_object_get (root, OIDC_CLIENT_ID_KEY);
1170 1520
1171 // REQUIRED value: client_id 1521 // REQUIRED value: client_id
1172 GNUNET_CRYPTO_hash (OIDC_CLIENT_ID_KEY, strlen (OIDC_CLIENT_ID_KEY), 1522 GNUNET_CRYPTO_hash (OIDC_CLIENT_ID_KEY, strlen (OIDC_CLIENT_ID_KEY),
@@ -1181,24 +1531,24 @@ authorize_cont (struct GNUNET_REST_RequestHandle *con_handle,
1181 } 1531 }
1182 client_id = GNUNET_CONTAINER_multihashmap_get(handle->rest_handle->url_param_map, 1532 client_id = GNUNET_CONTAINER_multihashmap_get(handle->rest_handle->url_param_map,
1183 &cache_key); 1533 &cache_key);
1184 struct GNUNET_CRYPTO_EcdsaPublicKey pubkey; 1534 if ( GNUNET_OK
1185 GNUNET_CRYPTO_ecdsa_public_key_from_string(client_id, 1535 != GNUNET_CRYPTO_ecdsa_public_key_from_string (client_id,
1186 strlen (client_id), 1536 strlen (client_id),
1187 &pubkey); 1537 &pubkey) )
1188// GNUNET_NAMESTORE_zone_to_name(); 1538 {
1539 handle->emsg=GNUNET_strdup("unauthorized_client");
1540 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1541 GNUNET_SCHEDULER_add_now (&do_error, handle);
1542 }
1543
1189 // Checks if client_id is valid: 1544 // Checks if client_id is valid:
1190 // TODO use GNUNET_NAMESTORE_zone_to_name() function to verify that a delegation to the client_id exists 1545 namestore_handle = GNUNET_NAMESTORE_connect(cfg);
1191 // TODO change check (lookup trusted public_key?) 1546 zone_pkey = GNUNET_IDENTITY_ego_get_private_key (handle->ego_entry->ego);
1192// if( strcmp( client_id, "localhost" ) != 0 ) 1547 GNUNET_NAMESTORE_zone_to_name (namestore_handle, zone_pkey, &pubkey,
1193// { 1548 zone_to_name_error, handle, zone_to_name_cb,
1194// handle->emsg=GNUNET_strdup("unauthorized_client"); 1549 handle);
1195// handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1196// GNUNET_SCHEDULER_add_now (&do_error, handle);
1197// return;
1198// }
1199 1550
1200 // REQUIRED value: redirect_uri 1551 // REQUIRED value: redirect_uri
1201 // TODO verify the redirect uri matches https://<client_id>.zkey[/xyz]
1202 GNUNET_CRYPTO_hash (OIDC_REDIRECT_URI_KEY, strlen (OIDC_REDIRECT_URI_KEY), 1552 GNUNET_CRYPTO_hash (OIDC_REDIRECT_URI_KEY, strlen (OIDC_REDIRECT_URI_KEY),
1203 &cache_key); 1553 &cache_key);
1204 if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle->url_param_map, 1554 if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle->url_param_map,
@@ -1212,15 +1562,17 @@ authorize_cont (struct GNUNET_REST_RequestHandle *con_handle,
1212 redirect_uri = GNUNET_CONTAINER_multihashmap_get(handle->rest_handle->url_param_map, 1562 redirect_uri = GNUNET_CONTAINER_multihashmap_get(handle->rest_handle->url_param_map,
1213 &cache_key); 1563 &cache_key);
1214 1564
1565 GNUNET_asprintf (&expected_redirect_uri, "https://%s.zkey", client_id);
1566
1215 // verify the redirect uri matches https://<client_id>.zkey[/xyz] 1567 // verify the redirect uri matches https://<client_id>.zkey[/xyz]
1216 // TODO change check (check client_id->public key == address) 1568 if( 0 != strncmp( expected_redirect_uri, redirect_uri, strlen(expected_redirect_uri)) )
1217// if( strcmp( redirect_uri, "https://localhost:8000" ) != 0 ) 1569 {
1218// { 1570 handle->emsg=GNUNET_strdup("invalid_request");
1219// handle->emsg=GNUNET_strdup("invalid_request"); 1571 handle->edesc=GNUNET_strdup("Invalid redirect_uri");
1220// handle->edesc=GNUNET_strdup("Invalid or mismatching redirect_uri"); 1572 GNUNET_free(expected_redirect_uri);
1221// GNUNET_SCHEDULER_add_now (&do_error, handle); 1573 GNUNET_SCHEDULER_add_now (&do_error, handle);
1222// return; 1574 return;
1223// } 1575 }
1224 handle->eredirect = GNUNET_strdup(redirect_uri); 1576 handle->eredirect = GNUNET_strdup(redirect_uri);
1225 1577
1226 // REQUIRED value: response_type 1578 // REQUIRED value: response_type
@@ -1268,8 +1620,7 @@ authorize_cont (struct GNUNET_REST_RequestHandle *con_handle,
1268 &cache_key); 1620 &cache_key);
1269 } 1621 }
1270 1622
1271 int number_of_ignored_parameter = sizeof(OIDC_ignored_parameter_array) / sizeof(char *); 1623 number_of_ignored_parameter = sizeof(OIDC_ignored_parameter_array) / sizeof(char *);
1272 int iterator;
1273 for( iterator = 0; iterator < number_of_ignored_parameter; iterator++ ) 1624 for( iterator = 0; iterator < number_of_ignored_parameter; iterator++ )
1274 { 1625 {
1275 GNUNET_CRYPTO_hash (OIDC_ignored_parameter_array[iterator], 1626 GNUNET_CRYPTO_hash (OIDC_ignored_parameter_array[iterator],
@@ -1279,15 +1630,15 @@ authorize_cont (struct GNUNET_REST_RequestHandle *con_handle,
1279 &cache_key)) 1630 &cache_key))
1280 { 1631 {
1281 handle->emsg=GNUNET_strdup("access_denied"); 1632 handle->emsg=GNUNET_strdup("access_denied");
1282 //TODO rewrite error description 1633 GNUNET_asprintf (*handle->edesc, "Server will not handle parameter: %s",
1283 handle->edesc=GNUNET_strdup("Server will not handle parameter"); 1634 OIDC_ignored_parameter_array[iterator]);
1284 GNUNET_SCHEDULER_add_now (&do_redirect_error, handle); 1635 GNUNET_SCHEDULER_add_now (&do_redirect_error, handle);
1285 return; 1636 return;
1286 } 1637 }
1287 } 1638 }
1288 1639
1289 // Checks if response_type is 'code' 1640 // Checks if response_type is 'code'
1290 if( strcmp( response_type, OIDC_EXPECTED_AUTHORIZATION_RESPONSE_TYPE ) != 0 ) 1641 if( 0 != strcmp( response_type, OIDC_EXPECTED_AUTHORIZATION_RESPONSE_TYPE ) )
1291 { 1642 {
1292 handle->emsg=GNUNET_strdup("unsupported_response_type"); 1643 handle->emsg=GNUNET_strdup("unsupported_response_type");
1293 handle->edesc=GNUNET_strdup("The authorization server does not support " 1644 handle->edesc=GNUNET_strdup("The authorization server does not support "
@@ -1296,7 +1647,7 @@ authorize_cont (struct GNUNET_REST_RequestHandle *con_handle,
1296 return; 1647 return;
1297 } 1648 }
1298 // Checks if scope contains 'openid' 1649 // Checks if scope contains 'openid'
1299 if( strstr( scope, OIDC_EXPECTED_AUTHORIZATION_SCOPE ) == NULL ) 1650 if( NULL == strstr( scope, OIDC_EXPECTED_AUTHORIZATION_SCOPE ) )
1300 { 1651 {
1301 handle->emsg=GNUNET_strdup("invalid_scope"); 1652 handle->emsg=GNUNET_strdup("invalid_scope");
1302 handle->edesc=GNUNET_strdup("The requested scope is invalid, unknown, or " 1653 handle->edesc=GNUNET_strdup("The requested scope is invalid, unknown, or "
@@ -1305,10 +1656,8 @@ authorize_cont (struct GNUNET_REST_RequestHandle *con_handle,
1305 return; 1656 return;
1306 } 1657 }
1307 1658
1308
1309 //TODO check other values and use them accordingly 1659 //TODO check other values and use them accordingly
1310 1660
1311
1312 GNUNET_CRYPTO_hash (OIDC_COOKIE_HEADER_KEY, strlen (OIDC_COOKIE_HEADER_KEY), 1661 GNUNET_CRYPTO_hash (OIDC_COOKIE_HEADER_KEY, strlen (OIDC_COOKIE_HEADER_KEY),
1313 &cache_key); 1662 &cache_key);
1314 //No identity-cookie -> redirect to login 1663 //No identity-cookie -> redirect to login
@@ -1323,13 +1672,13 @@ authorize_cont (struct GNUNET_REST_RequestHandle *con_handle,
1323 char *identity_cookie; 1672 char *identity_cookie;
1324 identity_cookie = strtok(cookies, delimiter); 1673 identity_cookie = strtok(cookies, delimiter);
1325 1674
1326 while(identity_cookie != NULL) 1675 while ( NULL != identity_cookie )
1327 { 1676 {
1328 if(strstr( identity_cookie, OIDC_COOKIE_HEADER_INFORMATION_KEY ) != NULL) 1677 if ( NULL != strstr (identity_cookie, OIDC_COOKIE_HEADER_INFORMATION_KEY) )
1329 { 1678 {
1330 break; 1679 break;
1331 } 1680 }
1332 identity_cookie = strtok(NULL, delimiter); 1681 identity_cookie = strtok (NULL, delimiter);
1333 } 1682 }
1334 GNUNET_CRYPTO_hash (identity_cookie, strlen (identity_cookie), &cache_key); 1683 GNUNET_CRYPTO_hash (identity_cookie, strlen (identity_cookie), &cache_key);
1335 1684
@@ -1348,8 +1697,30 @@ authorize_cont (struct GNUNET_REST_RequestHandle *con_handle,
1348 if ( current_time.abs_value_us <= relog_time->abs_value_us ) 1697 if ( current_time.abs_value_us <= relog_time->abs_value_us )
1349 { 1698 {
1350 resp = GNUNET_REST_create_response (""); 1699 resp = GNUNET_REST_create_response ("");
1351 // code = struct GNUNET_IDENTITY_PROVIDER_Ticket 1700
1352 GNUNET_IDENTITY_PROVIDER_t 1701 GNUNET_CRYPTO_ecdsa_public_key_from_string (identity_cookie,
1702 strlen (identity_cookie),
1703 &pubkey);
1704
1705 // iterate over egos and compare their public key
1706// GNUNET_IDENTITY_PROVIDER_get_attributes_start
1707 // iterate over scope variables
1708 char delimiter[] = " ";
1709 char *scope_attribute;
1710 scope_attribute = strtok(scope, delimiter);
1711
1712 while ( NULL != scope_attribute )
1713 {
1714 if ( NULL == strstr (scope_attribute, OIDC_EXPECTED_AUTHORIZATION_SCOPE) )
1715 {
1716 // claim attribute from ego
1717 scope_attribute = strtok (NULL, delimiter);
1718 }
1719 }
1720 // create an authorization code
1721
1722// GNUNET_IDENTITY_PROVIDER_t
1723
1353 MHD_add_response_header (resp, "Location", redirect_uri); 1724 MHD_add_response_header (resp, "Location", redirect_uri);
1354 handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND); 1725 handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND);
1355 cleanup_handle (handle); 1726 cleanup_handle (handle);
@@ -1459,9 +1830,9 @@ init_cont (struct RequestHandle *handle)
1459 {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_ATTRIBUTES, &list_attribute_cont}, 1830 {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_ATTRIBUTES, &list_attribute_cont},
1460 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_ATTRIBUTES, &add_attribute_cont}, 1831 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_ATTRIBUTES, &add_attribute_cont},
1461 {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_TICKETS, &list_tickets_cont}, 1832 {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_TICKETS, &list_tickets_cont},
1462 {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_AUTHORIZE, &authorize_cont}, 1833 {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_AUTHORIZE, &authorize_get_cont},
1463 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_LOGIN, &login_cont}, 1834 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_LOGIN, &login_cont},
1464 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_AUTHORIZE, &authorize_cont}, 1835 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_AUTHORIZE, &authorize_post_cont},
1465 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_REVOKE, &revoke_ticket_cont}, 1836 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_REVOKE, &revoke_ticket_cont},
1466 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_CONSUME, &consume_ticket_cont}, 1837 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_CONSUME, &consume_ticket_cont},
1467 {MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_IDENTITY_PROVIDER, 1838 {MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_IDENTITY_PROVIDER,