diff options
author | Phil <phil.buschmann@tum.de> | 2017-12-14 17:42:44 +0100 |
---|---|---|
committer | Phil <phil.buschmann@tum.de> | 2017-12-14 17:42:44 +0100 |
commit | a38dbfc3c3b80214d2eb1a165c1d8c123c73c8ae (patch) | |
tree | 8c19cf9531ea2968224207bfa60a227e88a7f223 /src/identity-provider | |
parent | e87ca099f191647b1c218fc213463433366db447 (diff) | |
download | gnunet-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.c | 229 |
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 | */ |
152 | struct GNUNET_CONTAINER_MultiHashMap *OIDC_authorize_time = | 162 | struct 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 | */ | ||
1412 | static void | ||
1413 | login_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}, |