aboutsummaryrefslogtreecommitdiff
path: root/src/identity-provider
diff options
context:
space:
mode:
authorPhil <phil.buschmann@tum.de>2017-12-14 17:42:44 +0100
committerPhil <phil.buschmann@tum.de>2017-12-14 17:42:44 +0100
commita38dbfc3c3b80214d2eb1a165c1d8c123c73c8ae (patch)
tree8c19cf9531ea2968224207bfa60a227e88a7f223 /src/identity-provider
parente87ca099f191647b1c218fc213463433366db447 (diff)
downloadgnunet-a38dbfc3c3b80214d2eb1a165c1d8c123c73c8ae.tar.gz
gnunet-a38dbfc3c3b80214d2eb1a165c1d8c123c73c8ae.zip
-add login and login timeout
Diffstat (limited to 'src/identity-provider')
-rw-r--r--src/identity-provider/plugin_rest_identity_provider.c229
1 files changed, 165 insertions, 64 deletions
diff --git a/src/identity-provider/plugin_rest_identity_provider.c b/src/identity-provider/plugin_rest_identity_provider.c
index be833faa9..58553bfeb 100644
--- a/src/identity-provider/plugin_rest_identity_provider.c
+++ b/src/identity-provider/plugin_rest_identity_provider.c
@@ -71,6 +71,11 @@
71#define GNUNET_REST_API_NS_AUTHORIZE "/idp/authorize" 71#define GNUNET_REST_API_NS_AUTHORIZE "/idp/authorize"
72 72
73/** 73/**
74 * Login namespace
75 */
76#define GNUNET_REST_API_NS_LOGIN "/idp/login"
77
78/**
74 * Attribute key 79 * Attribute key
75 */ 80 */
76#define GNUNET_REST_JSONAPI_IDENTITY_ATTRIBUTE "attribute" 81#define GNUNET_REST_JSONAPI_IDENTITY_ATTRIBUTE "attribute"
@@ -127,6 +132,11 @@
127#define OIDC_NONCE_KEY "nonce" 132#define OIDC_NONCE_KEY "nonce"
128 133
129/** 134/**
135 * OIDC authorization header key
136 */
137#define OIDC_AUTHORIZATION_HEADER_KEY "Authorization"
138
139/**
130 * OIDC expected response_type while authorizing 140 * OIDC expected response_type while authorizing
131 */ 141 */
132#define OIDC_EXPECTED_AUTHORIZATION_RESPONSE_TYPE "code" 142#define OIDC_EXPECTED_AUTHORIZATION_RESPONSE_TYPE "code"
@@ -147,10 +157,9 @@ char* OIDC_ignored_parameter_array [] =
147}; 157};
148 158
149/** 159/**
150 * OIDC authorize clients and times hashmap 160 * OIDC authorized identities and times hashmap
151 */ 161 */
152struct GNUNET_CONTAINER_MultiHashMap *OIDC_authorize_time = 162struct GNUNET_CONTAINER_MultiHashMap *OIDC_authorized_identities;
153 GNUNET_CONTAINER_multihashmap_create( 0, GNUNET_NO );
154 163
155/** 164/**
156 * The configuration handle 165 * The configuration handle
@@ -296,6 +305,11 @@ struct RequestHandle
296 char *emsg; 305 char *emsg;
297 306
298 /** 307 /**
308 * Error response uri
309 */
310 char *eredirect;
311
312 /**
299 * Error response description 313 * Error response description
300 */ 314 */
301 char *edesc; 315 char *edesc;
@@ -394,8 +408,8 @@ do_redirect_error (void *cls)
394 char* redirect; 408 char* redirect;
395 //TODO handle->url is wrong 409 //TODO handle->url is wrong
396 GNUNET_asprintf (&redirect, 410 GNUNET_asprintf (&redirect,
397 "http://localhost:8000%s?error=%s&error_description=%s", 411 "%s?error=%s&error_description=%s",
398 handle->rest_handle->url, handle->emsg, handle->edesc ); 412 handle->eredirect, handle->emsg, handle->edesc );
399 resp = GNUNET_REST_create_response (""); 413 resp = GNUNET_REST_create_response ("");
400 MHD_add_response_header (resp, "Location", redirect); 414 MHD_add_response_header (resp, "Location", redirect);
401 handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND); 415 handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND);
@@ -1115,15 +1129,16 @@ authorize_cont (struct GNUNET_REST_RequestHandle *con_handle,
1115 struct RequestHandle *handle = cls; 1129 struct RequestHandle *handle = cls;
1116 char *response_type, *client_id, *scope, *redirect_uri, *state = 0, 1130 char *response_type, *client_id, *scope, *redirect_uri, *state = 0,
1117 *nonce = 0; 1131 *nonce = 0;
1132 struct timeval now, login_time;
1133 OIDC_authorized_identities = GNUNET_CONTAINER_multihashmap_create( 10, GNUNET_NO );
1134 char *login_base_url, *new_redirect;
1135 struct GNUNET_HashCode cache_key;
1118 1136
1119 //TODO clean up method 1137 //TODO clean up method
1120 1138
1121 /** The Authorization Server MUST validate all the OAuth 2.0 parameters 1139 /** The Authorization Server MUST validate all the OAuth 2.0 parameters
1122 * according to the OAuth 2.0 specification. 1140 * according to the OAuth 2.0 specification.
1123 */ 1141 */
1124 /** The Authorization Server MUST verify that all the REQUIRED parameters
1125 * are present and their usage conforms to this specification.
1126 */
1127 /** 1142 /**
1128 * If the sub (subject) Claim is requested with a specific value for the 1143 * If the sub (subject) Claim is requested with a specific value for the
1129 * ID Token, the Authorization Server MUST only send a positive response 1144 * ID Token, the Authorization Server MUST only send a positive response
@@ -1137,7 +1152,7 @@ authorize_cont (struct GNUNET_REST_RequestHandle *con_handle,
1137 * the implementation. 1152 * the implementation.
1138 */ 1153 */
1139 1154
1140 struct GNUNET_HashCode cache_key; 1155
1141 1156
1142 // REQUIRED value: client_id 1157 // REQUIRED value: client_id
1143 GNUNET_CRYPTO_hash (OIDC_CLIENT_ID_KEY, strlen (OIDC_CLIENT_ID_KEY), 1158 GNUNET_CRYPTO_hash (OIDC_CLIENT_ID_KEY, strlen (OIDC_CLIENT_ID_KEY),
@@ -1155,13 +1170,13 @@ authorize_cont (struct GNUNET_REST_RequestHandle *con_handle,
1155 1170
1156 // Checks if client_id is valid: 1171 // Checks if client_id is valid:
1157 // TODO change check (lookup trusted public_key?) 1172 // TODO change check (lookup trusted public_key?)
1158 if( strcmp( client_id, "localhost" ) != 0 ) 1173// if( strcmp( client_id, "localhost" ) != 0 )
1159 { 1174// {
1160 handle->emsg=GNUNET_strdup("unauthorized_client"); 1175// handle->emsg=GNUNET_strdup("unauthorized_client");
1161 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; 1176// handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1162 GNUNET_SCHEDULER_add_now (&do_redirect_error, handle); 1177// GNUNET_SCHEDULER_add_now (&do_error, handle);
1163 return; 1178// return;
1164 } 1179// }
1165 1180
1166 // REQUIRED value: redirect_uri 1181 // REQUIRED value: redirect_uri
1167 GNUNET_CRYPTO_hash (OIDC_REDIRECT_URI_KEY, strlen (OIDC_REDIRECT_URI_KEY), 1182 GNUNET_CRYPTO_hash (OIDC_REDIRECT_URI_KEY, strlen (OIDC_REDIRECT_URI_KEY),
@@ -1178,14 +1193,15 @@ authorize_cont (struct GNUNET_REST_RequestHandle *con_handle,
1178 &cache_key); 1193 &cache_key);
1179 1194
1180 // Checks if redirect_uri is valid: 1195 // Checks if redirect_uri is valid:
1181 // TODO change check (check public key == address) 1196 // TODO change check (check client_id->public key == address)
1182 if( strcmp( redirect_uri, "https://localhost:8000" ) != 0 ) 1197// if( strcmp( redirect_uri, "https://localhost:8000" ) != 0 )
1183 { 1198// {
1184 handle->emsg=GNUNET_strdup("invalid_request"); 1199// handle->emsg=GNUNET_strdup("invalid_request");
1185 handle->edesc=GNUNET_strdup("Invalid or mismatching redirect_uri"); 1200// handle->edesc=GNUNET_strdup("Invalid or mismatching redirect_uri");
1186 GNUNET_SCHEDULER_add_now (&do_error, handle); 1201// GNUNET_SCHEDULER_add_now (&do_error, handle);
1187 return; 1202// return;
1188 } 1203// }
1204 handle->eredirect = GNUNET_strdup(redirect_uri);
1189 1205
1190 // REQUIRED value: response_type 1206 // REQUIRED value: response_type
1191 GNUNET_CRYPTO_hash (OIDC_RESPONSE_TYPE_KEY, strlen (OIDC_RESPONSE_TYPE_KEY), 1207 GNUNET_CRYPTO_hash (OIDC_RESPONSE_TYPE_KEY, strlen (OIDC_RESPONSE_TYPE_KEY),
@@ -1273,68 +1289,152 @@ authorize_cont (struct GNUNET_REST_RequestHandle *con_handle,
1273 //TODO check other values and use them accordingly 1289 //TODO check other values and use them accordingly
1274 1290
1275 1291
1276 char* login_base_url; 1292
1277 char* new_redirect;
1278 1293
1279 //if header-authorization == ID 1294 //if header-authorization == ID
1280 //if ID is still logged 1295 //if ID is still logged
1281 // ego get Public Key of Identity 1296 // ego get Public Key of Identity
1282 // return token with public key? 1297 // return token with public key?
1283 // else: 1298 // save request
1284 char* id="reterte"; 1299
1285 1300 GNUNET_CRYPTO_hash (OIDC_AUTHORIZATION_HEADER_KEY,
1286 1301 strlen (OIDC_AUTHORIZATION_HEADER_KEY),
1287 GNUNET_CRYPTO_hash (id, strlen (id), &cache_key); 1302 &cache_key);
1288 1303 //No Authorization Parameter -> redirect to login
1289 if(GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains(OIDC_authorize_time, 1304 if(GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains(con_handle->header_param_map,
1290 &cache_key)) 1305 &cache_key))
1291 { 1306 {
1292 struct timeval login_time = GNUNET_CONTAINER_multihashmap_get(OIDC_authorize_time, &cache_key); 1307 if ( GNUNET_OK
1293 struct timeval now; 1308 == GNUNET_CONFIGURATION_get_value_string (cfg, "identity-rest-plugin",
1294 gettimeofday(&now); 1309 "address", &login_base_url) )
1295 //After 30 minutes force login process
1296 if((login_time.tv_sec+30*60) <= now.tv_sec)
1297 { 1310 {
1298 // login 1311 GNUNET_asprintf (&new_redirect, "%s?%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s",
1312 login_base_url,
1313 OIDC_RESPONSE_TYPE_KEY,
1314 response_type,
1315 OIDC_CLIENT_ID_KEY,
1316 client_id,
1317 OIDC_REDIRECT_URI_KEY,
1318 redirect_uri,
1319 OIDC_SCOPE_KEY,
1320 scope,
1321 OIDC_STATE_KEY,
1322 (state) ? state : "",
1323 OIDC_NONCE_KEY,
1324 (nonce) ? nonce : "");
1325 resp = GNUNET_REST_create_response ("");
1326 MHD_add_response_header (resp, "Location", new_redirect);
1299 } 1327 }
1300 else 1328 else
1301 { 1329 {
1302 // redirect 1330 handle->emsg = GNUNET_strdup("No server configuration");
1331 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1332 GNUNET_SCHEDULER_add_now (&do_error, handle);
1333 return;
1303 } 1334 }
1335 handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND);
1336 cleanup_handle (handle);
1337 GNUNET_free(new_redirect);
1338 return;
1304 } 1339 }
1305 else 1340 else
1306 { 1341 {
1307 // login 1342 char* identity = GNUNET_CONTAINER_multihashmap_get ( con_handle->header_param_map,
1343 &cache_key);
1344 GNUNET_CRYPTO_hash (identity, strlen (identity), &cache_key);
1345 if(GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains(OIDC_authorized_identities,
1346 &cache_key))
1347 {
1348 login_time = *(struct timeval *)GNUNET_CONTAINER_multihashmap_get(OIDC_authorized_identities,
1349 &cache_key);
1350 gettimeofday(&now, NULL);
1351 //After 30 minutes redirect to login
1352 if( now.tv_sec - login_time.tv_sec >= 1800)
1353 {
1354 //TODO remove redundancy [redirect to login]
1355 if ( GNUNET_OK
1356 == GNUNET_CONFIGURATION_get_value_string (cfg, "identity-rest-plugin",
1357 "address", &login_base_url) )
1358 {
1359 GNUNET_asprintf (&new_redirect, "%s?%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s",
1360 login_base_url,
1361 OIDC_RESPONSE_TYPE_KEY,
1362 response_type,
1363 OIDC_CLIENT_ID_KEY,
1364 client_id,
1365 OIDC_REDIRECT_URI_KEY,
1366 redirect_uri,
1367 OIDC_SCOPE_KEY,
1368 scope,
1369 OIDC_STATE_KEY,
1370 (state) ? state : "",
1371 OIDC_NONCE_KEY,
1372 (nonce) ? nonce : "");
1373 resp = GNUNET_REST_create_response ("");
1374 MHD_add_response_header (resp, "Location", new_redirect);
1375 }
1376 else
1377 {
1378 handle->emsg = GNUNET_strdup("No server configuration");
1379 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1380 GNUNET_SCHEDULER_add_now (&do_error, handle);
1381 return;
1382 }
1383 handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND);
1384 cleanup_handle (handle);
1385 GNUNET_free(new_redirect);
1386 return;
1387 }
1388 }
1389 else
1390 {
1391 gettimeofday( &now, NULL );
1392 GNUNET_CONTAINER_multihashmap_put( OIDC_authorized_identities, &cache_key, &now,
1393 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
1394 }
1395 resp = GNUNET_REST_create_response ("");
1396// MHD_add_response_header (resp, "Access-Control-Allow-Origin", "*");
1397 MHD_add_response_header (resp, "Location", redirect_uri);
1398 handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND);
1399 cleanup_handle (handle);
1400 return;
1308 } 1401 }
1402}
1309 1403
1310 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg, 1404
1311 "identity-rest-plugin", 1405/**
1312 "address", 1406 * Respond to LOGIN request
1313 &login_base_url)) 1407 *
1408 * @param con_handle the connection handle
1409 * @param url the url
1410 * @param cls the RequestHandle
1411 */
1412static void
1413login_cont (struct GNUNET_REST_RequestHandle *con_handle,
1414 const char* url,
1415 void *cls)
1416{
1417 struct MHD_Response *resp = GNUNET_REST_create_response ("");
1418 struct RequestHandle *handle = cls;
1419 char* cookie;
1420 json_t *root;
1421 json_error_t error;
1422 json_t *identity;
1423 root = json_loads( handle->rest_handle->data, 0, &error );
1424 identity = json_object_get(root, "identity");
1425 if(json_is_string(identity))
1314 { 1426 {
1315 GNUNET_asprintf (&new_redirect, "%s?%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s", 1427 GNUNET_asprintf(&cookie,"Identity=%s",json_string_value(identity));
1316 login_base_url, 1428 MHD_add_response_header (resp, "Set-Cookie", cookie);
1317 OIDC_RESPONSE_TYPE_KEY, response_type, 1429 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
1318 OIDC_CLIENT_ID_KEY, client_id,
1319 OIDC_REDIRECT_URI_KEY, redirect_uri,
1320 OIDC_SCOPE_KEY, scope,
1321 OIDC_STATE_KEY, ( state )? state : "",
1322 OIDC_NONCE_KEY, ( nonce )? nonce : ""
1323 );
1324 resp = GNUNET_REST_create_response ("");
1325 MHD_add_response_header (resp, "Location", new_redirect);
1326 } 1430 }
1327 else 1431 else
1328 { 1432 {
1329 handle->emsg=GNUNET_strdup("No server configuration"); 1433 handle->proc (handle->proc_cls, resp, MHD_HTTP_BAD_REQUEST);
1330 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1331 GNUNET_SCHEDULER_add_now (&do_error, handle);
1332 return;
1333 } 1434 }
1334 1435 json_decref(root);
1335 handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND);
1336 cleanup_handle (handle); 1436 cleanup_handle (handle);
1337 GNUNET_free(new_redirect); 1437 GNUNET_free(cookie);
1338 return; 1438 return;
1339} 1439}
1340 1440
@@ -1352,6 +1452,7 @@ init_cont (struct RequestHandle *handle)
1352 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_ATTRIBUTES, &add_attribute_cont}, 1452 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_ATTRIBUTES, &add_attribute_cont},
1353 {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_TICKETS, &list_tickets_cont}, 1453 {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_TICKETS, &list_tickets_cont},
1354 {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_AUTHORIZE, &authorize_cont}, 1454 {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_AUTHORIZE, &authorize_cont},
1455 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_LOGIN, &login_cont},
1355 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_AUTHORIZE, &authorize_cont}, 1456 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_AUTHORIZE, &authorize_cont},
1356 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_REVOKE, &revoke_ticket_cont}, 1457 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_REVOKE, &revoke_ticket_cont},
1357 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_CONSUME, &consume_ticket_cont}, 1458 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_CONSUME, &consume_ticket_cont},