aboutsummaryrefslogtreecommitdiff
path: root/src/rest/gnunet-rest-server.c
diff options
context:
space:
mode:
authorMartin Schanzenbach <schanzen@gnunet.org>2022-09-08 22:17:34 +0200
committerMartin Schanzenbach <schanzen@gnunet.org>2022-09-08 22:17:34 +0200
commit9ee1ef3d55721c37bac0978c0e7ead0c9c49eef1 (patch)
tree2241b071bcde8a6cd24aca3d1e8f93f66cb54f6a /src/rest/gnunet-rest-server.c
parent0b07a5569648e37633fedd3abd06592d19d41dee (diff)
downloadgnunet-9ee1ef3d55721c37bac0978c0e7ead0c9c49eef1.tar.gz
gnunet-9ee1ef3d55721c37bac0978c0e7ead0c9c49eef1.zip
REST: Implement basic authentication for per user service. Fixes #5669
Diffstat (limited to 'src/rest/gnunet-rest-server.c')
-rw-r--r--src/rest/gnunet-rest-server.c112
1 files changed, 106 insertions, 6 deletions
diff --git a/src/rest/gnunet-rest-server.c b/src/rest/gnunet-rest-server.c
index 63847587b..9984478ce 100644
--- a/src/rest/gnunet-rest-server.c
+++ b/src/rest/gnunet-rest-server.c
@@ -120,6 +120,21 @@ static const struct GNUNET_CONFIGURATION_Handle *cfg;
120static int echo_origin; 120static int echo_origin;
121 121
122/** 122/**
123 * Do basic auth of user
124 */
125static int basic_auth_enabled;
126
127/**
128 * Basic auth secret
129 */
130static char *basic_auth_secret;
131
132/**
133 * User of the service
134 */
135char cuser[LOGIN_NAME_MAX];
136
137/**
123 * Allowed Origins (CORS) 138 * Allowed Origins (CORS)
124 */ 139 */
125static char *allow_origins; 140static char *allow_origins;
@@ -318,7 +333,8 @@ cleanup_ar (struct AcceptedRequest *ar)
318 if (GNUNET_YES == ar->socket_with_mhd) 333 if (GNUNET_YES == ar->socket_with_mhd)
319 { 334 {
320 GNUNET_NETWORK_socket_free_memory_only_ (ar->sock); 335 GNUNET_NETWORK_socket_free_memory_only_ (ar->sock);
321 } else { 336 }
337 else {
322 GNUNET_NETWORK_socket_close (ar->sock); 338 GNUNET_NETWORK_socket_close (ar->sock);
323 } 339 }
324 ar->sock = NULL; 340 ar->sock = NULL;
@@ -463,6 +479,8 @@ create_response (void *cls,
463 void **con_cls) 479 void **con_cls)
464{ 480{
465 char *origin; 481 char *origin;
482 char *pw;
483 char *user;
466 struct AcceptedRequest *ar; 484 struct AcceptedRequest *ar;
467 struct GNUNET_HashCode key; 485 struct GNUNET_HashCode key;
468 struct MhdConnectionHandle *con_handle; 486 struct MhdConnectionHandle *con_handle;
@@ -506,6 +524,29 @@ create_response (void *cls,
506 MHD_HEADER_KIND, 524 MHD_HEADER_KIND,
507 (MHD_KeyValueIterator) & header_iterator, 525 (MHD_KeyValueIterator) & header_iterator,
508 rest_conndata_handle); 526 rest_conndata_handle);
527 if (GNUNET_YES == basic_auth_enabled)
528 {
529 pw = NULL;
530 user = MHD_basic_auth_get_username_password (con, &pw);
531 if ((NULL == user) ||
532 (0 != strcmp (user, cuser)))
533 {
534 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
535 "Unknown user %s\n", user);
536 MHD_queue_basic_auth_fail_response (con, "gnunet", failure_response);
537 return MHD_YES;
538 }
539 if ((NULL == pw) ||
540 (0 != strcmp (pw, basic_auth_secret)))
541 {
542 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
543 "Password incorrect\n");
544 MHD_queue_basic_auth_fail_response (con, "gnunet", failure_response);
545 GNUNET_free (pw);
546 return MHD_YES;
547 }
548 GNUNET_free (pw);
549 }
509 550
510 con_handle->pp = MHD_create_post_processor (con, 551 con_handle->pp = MHD_create_post_processor (con,
511 65536, 552 65536,
@@ -540,7 +581,7 @@ create_response (void *cls,
540 MHD_suspend_connection (con_handle->con); 581 MHD_suspend_connection (con_handle->con);
541 return MHD_YES; 582 return MHD_YES;
542 } 583 }
543 //MHD_resume_connection (con_handle->con); 584 // MHD_resume_connection (con_handle->con);
544 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 585 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
545 "Queueing response from plugin with MHD\n"); 586 "Queueing response from plugin with MHD\n");
546 // Handle Preflights for extensions 587 // Handle Preflights for extensions
@@ -601,7 +642,7 @@ create_response (void *cls,
601 MHD_RESULT ret = MHD_queue_response (con, 642 MHD_RESULT ret = MHD_queue_response (con,
602 con_handle->status, 643 con_handle->status,
603 con_handle->response); 644 con_handle->response);
604 //cleanup_handle (con_handle); 645 // cleanup_handle (con_handle);
605 return ret; 646 return ret;
606 } 647 }
607} 648}
@@ -1065,6 +1106,8 @@ run (void *cls,
1065 const struct GNUNET_CONFIGURATION_Handle *c) 1106 const struct GNUNET_CONFIGURATION_Handle *c)
1066{ 1107{
1067 char *addr_str; 1108 char *addr_str;
1109 char *basic_auth_file;
1110 uint64_t secret;
1068 1111
1069 cfg = c; 1112 cfg = c;
1070 plugins_head = NULL; 1113 plugins_head = NULL;
@@ -1119,6 +1162,62 @@ run (void *cls,
1119 } 1162 }
1120 GNUNET_free (addr_str); 1163 GNUNET_free (addr_str);
1121 1164
1165 basic_auth_enabled = GNUNET_CONFIGURATION_get_value_yesno (cfg,
1166 "rest",
1167 "BASIC_AUTH_ENABLED");
1168 if (basic_auth_enabled)
1169 {
1170 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg,
1171 "rest",
1172 "BASIC_AUTH_SECRET_FILE",
1173 &basic_auth_file))
1174 {
1175 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1176 "No basic auth secret file location set...\n");
1177 GNUNET_SCHEDULER_shutdown ();
1178 return;
1179 }
1180 if (GNUNET_YES != GNUNET_DISK_file_test (basic_auth_file))
1181 {
1182 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1183 "No basic auth secret found... generating\n");
1184 secret = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK,
1185 UINT64_MAX);
1186 basic_auth_secret = GNUNET_STRINGS_data_to_string_alloc (&secret,
1187 sizeof(secret));
1188 if (GNUNET_OK !=
1189 GNUNET_DISK_fn_write (basic_auth_file,
1190 basic_auth_secret,
1191 strlen (basic_auth_secret),
1192 GNUNET_DISK_PERM_USER_READ
1193 | GNUNET_DISK_PERM_USER_WRITE))
1194 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING,
1195 "write",
1196 basic_auth_file);
1197 }
1198 else
1199 {
1200 char basic_auth_secret_tmp[16]; // Should be more than enough
1201 memset (basic_auth_secret_tmp, 0, 16);
1202 if (GNUNET_SYSERR == GNUNET_DISK_fn_read (basic_auth_file,
1203 basic_auth_secret_tmp,
1204 sizeof (basic_auth_secret_tmp)))
1205 {
1206 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1207 "Unable to read basic auth secret file.\n");
1208 GNUNET_SCHEDULER_shutdown ();
1209 return;
1210 }
1211 if (0 != getlogin_r (cuser, LOGIN_NAME_MAX))
1212 {
1213 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1214 "Unable to get user.\n");
1215 GNUNET_SCHEDULER_shutdown ();
1216 return;
1217 }
1218 basic_auth_secret = GNUNET_strdup (basic_auth_secret_tmp);
1219 }
1220 }
1122 1221
1123 /* Get CORS data from cfg */ 1222 /* Get CORS data from cfg */
1124 echo_origin = 1223 echo_origin =
@@ -1155,7 +1254,7 @@ run (void *cls,
1155 "No CORS Access-Control-Allow-Headers Header will be sent...\n"); 1254 "No CORS Access-Control-Allow-Headers Header will be sent...\n");
1156 } 1255 }
1157 1256
1158 /* Open listen socket proxy */ 1257/* Open listen socket proxy */
1159 lsock6 = bind_v6 (); 1258 lsock6 = bind_v6 ();
1160 if (NULL == lsock6) 1259 if (NULL == lsock6)
1161 { 1260 {
@@ -1203,7 +1302,8 @@ run (void *cls,
1203 GNUNET_SCHEDULER_shutdown (); 1302 GNUNET_SCHEDULER_shutdown ();
1204 return; 1303 return;
1205 } 1304 }
1206 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Service listens on port %llu\n", port); 1305 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Service listens on port %llu\n",
1306 port);
1207 httpd = MHD_start_daemon (MHD_USE_DEBUG | MHD_USE_NO_LISTEN_SOCKET 1307 httpd = MHD_start_daemon (MHD_USE_DEBUG | MHD_USE_NO_LISTEN_SOCKET
1208 | MHD_ALLOW_SUSPEND_RESUME, 1308 | MHD_ALLOW_SUSPEND_RESUME,
1209 0, 1309 0,
@@ -1228,7 +1328,7 @@ run (void *cls,
1228 GNUNET_SCHEDULER_shutdown (); 1328 GNUNET_SCHEDULER_shutdown ();
1229 return; 1329 return;
1230 } 1330 }
1231 /* Load plugins */ 1331/* Load plugins */
1232 GNUNET_PLUGIN_load_all_in_context (GNUNET_OS_project_data_default (), 1332 GNUNET_PLUGIN_load_all_in_context (GNUNET_OS_project_data_default (),
1233 "libgnunet_plugin_rest", 1333 "libgnunet_plugin_rest",
1234 (void *) cfg, 1334 (void *) cfg,