aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2020-03-01 09:28:52 +0200
committerSergey Poznyakoff <gray@gnu.org>2020-03-01 09:28:52 +0200
commit3000780b55437ef04db32ec860719d16cd08978b (patch)
tree0fc1aac0623a58924ecf0981eba885c8df1e6ded
parent7aa8fc1f4a39dcad0cb5330aa4ac47afc924ecb0 (diff)
downloadping903-3000780b55437ef04db32ec860719d16cd08978b.tar.gz
ping903-3000780b55437ef04db32ec860719d16cd08978b.tar.bz2
/config,/id: Return a json object when a particular attribute is requested
* src/ping903.c (auth_flt): Fix memory overrun. (http_json_flt_response): New function. (ident_to_json,ept_config): Rewrite using http_json_flt_response. (try_auth): Squash repeated '/' characters.
-rw-r--r--src/ping903.c162
1 files changed, 68 insertions, 94 deletions
diff --git a/src/ping903.c b/src/ping903.c
index 5ab3f4d..549f42e 100644
--- a/src/ping903.c
+++ b/src/ping903.c
@@ -310,7 +310,7 @@ auth_flt(char const *kw, struct json_value *val, void *data)
{
int rc;
struct auth_flt_data *adata = data;
- char *url = malloc(strlen(adata->url) + strlen(kw) + 1);
+ char *url = malloc(strlen(adata->url) + strlen(kw) + 2);
if (!url) {
adata->err = 1;
return 0;
@@ -323,6 +323,55 @@ auth_flt(char const *kw, struct json_value *val, void *data)
return rc;
}
+static int
+attr_flt(char const *kw, struct json_value *val, void *data)
+{
+ return strcmp(kw, (char*)data);
+}
+
+static int
+http_json_flt_response(struct MHD_Connection *conn,
+ const char *url, const char *method,
+ struct json_value *val, const char *suffix)
+{
+ int ret;
+
+ if (!val)
+ return http_response(conn, method, url,
+ MHD_HTTP_INTERNAL_SERVER_ERROR);
+ while (*suffix == '/')
+ suffix++;
+ if (*suffix) {
+ if (json_object_filter(val, attr_flt, (void*)suffix)) {
+ ret = http_response(conn, method, url,
+ MHD_HTTP_INTERNAL_SERVER_ERROR);
+ json_value_free(val);
+ return ret;
+ }
+ if (!val->v.o->head) {
+ ret = http_response(conn, method, url,
+ MHD_HTTP_NOT_FOUND);
+ json_value_free(val);
+ return ret;
+ }
+ } else {
+ struct auth_flt_data adata = {
+ .conn = conn,
+ .url = url,
+ .method = method,
+ .err = 0
+ };
+ if (json_object_filter(val, auth_flt, &adata) || adata.err) {
+ ret = http_response(conn, method, url,
+ MHD_HTTP_INTERNAL_SERVER_ERROR);
+ json_value_free(val);
+ return ret;
+ }
+ }
+
+ return httpd_json_response(conn, url, method, MHD_HTTP_OK, val);
+}
+
static struct json_value *
ident_to_json(void)
{
@@ -352,49 +401,8 @@ ept_ident(struct MHD_Connection *conn,
const char *url, const char *method, const char *suffix,
struct json_value *unused)
{
- int ret;
- struct json_value *obj;
-
- while (*suffix == '/')
- suffix++;
- obj = ident_to_json();
- if (!obj)
- return http_response(conn, method, url,
- MHD_HTTP_INTERNAL_SERVER_ERROR);
- if (*suffix) {
- struct json_value *jv, *cp;
- if (json_object_get(obj, suffix, &jv)) {
- ret = http_response(conn, method, url,
- (errno == ENOENT)
- ? MHD_HTTP_NOT_FOUND
- : MHD_HTTP_INTERNAL_SERVER_ERROR);
- json_value_free(obj);
- return ret;
- }
-
- if (json_value_copy(jv, &cp)) {
- ret = http_response(conn, method, url,
- MHD_HTTP_INTERNAL_SERVER_ERROR);
- json_value_free(obj);
- return ret;
- }
- json_value_free(obj);
- obj = cp;
- } else {
- struct auth_flt_data adata = {
- .conn = conn,
- .url = url,
- .method = method,
- .err = 0
- };
- if (json_object_filter(obj, auth_flt, &adata) || adata.err) {
- int ret = http_response(conn, method, url,
- MHD_HTTP_INTERNAL_SERVER_ERROR);
- json_value_free(obj);
- return ret;
- }
- }
- return httpd_json_response(conn, url, method, MHD_HTTP_OK, obj);
+ return http_json_flt_response(conn, url, method,
+ ident_to_json(), suffix);
}
static int
@@ -402,53 +410,8 @@ ept_config(struct MHD_Connection *conn,
const char *url, const char *method, const char *suffix,
struct json_value *unused)
{
- struct json_value *val;
-
- while (*suffix == '/')
- suffix++;
-
- val = config_to_json();
- if (!val)
- return http_response(conn, method, url,
- MHD_HTTP_INTERNAL_SERVER_ERROR);
-
- if (*suffix) {
- struct json_value *jv, *cp;
- int ret;
-
- if (json_object_get(val, suffix, &jv)) {
- ret = http_response(conn, method, url,
- (errno == ENOENT)
- ? MHD_HTTP_NOT_FOUND
- : MHD_HTTP_INTERNAL_SERVER_ERROR);
- json_value_free(val);
- return ret;
- }
-
- if (json_value_copy(jv, &cp)) {
- ret = http_response(conn, method, url,
- MHD_HTTP_INTERNAL_SERVER_ERROR);
- json_value_free(val);
- return ret;
- }
- json_value_free(val);
- val = cp;
- } else {
- struct auth_flt_data adata = {
- .conn = conn,
- .url = url,
- .method = method,
- .err = 0
- };
- if (json_object_filter(val, auth_flt, &adata) || adata.err) {
- int ret = http_response(conn, method, url,
- MHD_HTTP_INTERNAL_SERVER_ERROR);
- json_value_free(val);
- return ret;
- }
- }
-
- return httpd_json_response(conn, url, method, MHD_HTTP_OK, val);
+ return http_json_flt_response(conn, url, method,
+ config_to_json(), suffix);
}
static int
@@ -873,7 +836,9 @@ try_auth(struct MHD_Connection *conn, const char *url, const char *method,
struct auth_location *loc;
size_t url_len;
char *url_buf;
-
+ char *p;
+ char const *q;
+
url_len = strcspn(url, "?");
while (url_len > 1 && url[url_len-1] == '/')
--url_len;
@@ -884,8 +849,17 @@ try_auth(struct MHD_Connection *conn, const char *url, const char *method,
MHD_HTTP_INTERNAL_SERVER_ERROR);
return 1;
}
- memcpy(url_buf, url, url_len);
- url_buf[url_len] = 0;
+
+ /* Copy url to url_buf squashing repeated '/' into a single slash */
+ p = url_buf;
+ q = url;
+ while (*q) {
+ if (!(*q == '/' && q > url && q[-1] == '/'))
+ *p++ = *q;
+ q++;
+ }
+ *p = 0;
+
for (loc = auth_head; loc; loc = loc->next) {
if (fnmatch(loc->method, method, 0))
continue;

Return to:

Send suggestions and report system problems to the System administrator.