source: ogServer-Git/src/cfg.c @ f068a79

Last change on this file since f068a79 was bdd8519, checked in by OpenGnSys Support Team <soporte-og@…>, 4 years ago

#988 use-after-free in json configuration parser

The cfg structure stores pointers to the string in this json tree. Do not
release the json tree, keep it as field in the cfg structure.

  • Property mode set to 100644
File size: 4.2 KB
RevLine 
[866b6c5]1/*
2 * Copyright (C) 2020 Soleta Networks <info@soleta.eu>
3 *
4 * This program is free software: you can redistribute it and/or modify it under
5 * the terms of the GNU Affero General Public License as published by the
6 * Free Software Foundation, version 3.
7 */
8
9#include "json.h"
10#include "cfg.h"
11#include "ogAdmServer.h"
12#include <sys/types.h>
13#include <sys/stat.h>
14#include <fcntl.h>
15#include <unistd.h>
16#include <syslog.h>
17
18static int parse_json_rest(struct og_server_cfg *cfg, json_t *element)
19{
20        const char *key;
21        json_t *value;
22
23        json_object_foreach(element, key, value) {
24                if (!strcmp(key, "ip")) {
25                        if (og_json_parse_string(value, &cfg->rest.ip) < 0)
26                                return -1;
27                } else if (!strcmp(key, "port")) {
28                        if (og_json_parse_string(value, &cfg->rest.port) < 0)
29                                return -1;
30                } else if (!strcmp(key, "api_token")) {
31                        if (og_json_parse_string(value, &cfg->rest.api_token) < 0)
32                                return -1;
33                } else {
34                        syslog(LOG_ERR, "unknown key `%s' in rest\n", key);
35                        return -1;
36                }
37        }
38
39        return 0;
40}
41
42static int parse_json_db(struct og_server_cfg *cfg, json_t *element)
43{
44        const char *key;
45        json_t *value;
46
47        json_object_foreach(element, key, value) {
48                if (!strcmp(key, "ip")) {
49                        if (og_json_parse_string(value, &cfg->db.ip) < 0)
50                                return -1;
51                } else if (!strcmp(key, "user")) {
52                        if (og_json_parse_string(value, &cfg->db.user) < 0)
53                                return -1;
54                } else if (!strcmp(key, "pass")) {
55                        if (og_json_parse_string(value, &cfg->db.pass) < 0)
56                                return -1;
57                } else if (!strcmp(key, "name")) {
58                        if (og_json_parse_string(value, &cfg->db.name) < 0)
59                                return -1;
[0631b0e]60                } else if (!strcmp(key, "port")) {
[a8e5b84]61                        if (og_json_parse_uint(value, &cfg->db.port) < 0 ||
62                            cfg->db.port > UINT16_MAX)
[0631b0e]63                                return -1;
[866b6c5]64                } else {
65                        syslog(LOG_ERR, "unknown key `%s' in db\n", key);
66                        return -1;
67                }
68        }
69
70        return 0;
71}
72
73static int parse_json_wol(struct og_server_cfg *cfg, json_t *element)
74{
75        const char *key;
76        json_t *value;
77
78        json_object_foreach(element, key, value) {
79                if (!strcmp(key, "interface")) {
80                        if (og_json_parse_string(value, &cfg->wol.interface) < 0)
81                                return -1;
82                } else {
83                        syslog(LOG_ERR, "unknown key `%s' in wol\n", key);
84                        return -1;
85                }
86        }
87
88        return 0;
89}
90
91#define OG_SERVER_CFG_REST      (1 << 0)
92#define OG_SERVER_CFG_DB        (1 << 1)
93#define OG_SERVER_CFG_WOL       (1 << 2)
94
95int parse_json_config(const char *filename, struct og_server_cfg *cfg)
96{
97        json_t *root, *value;
98        uint32_t flags = 0;
99        json_error_t err;
100        const char *key;
101        char buf[4096];
102        int fd, ret;
103
104        fd = open(filename, O_RDONLY);
[8215e0c]105        if (fd < 0) {
[866b6c5]106                syslog(LOG_ERR, "Cannot open %s", filename);
107                return -1;
108        }
109
110        ret = read(fd, buf, sizeof(buf));
111        if (ret < 0 || ret == sizeof(buf)) {
112                syslog(LOG_ERR, "Cannot read from %s", filename);
113                return -1;
114        }
115
116        root = json_loads(buf, 0, &err);
117        if (!root) {
118                syslog(LOG_ERR, "Cannot parse malformed json file");
119                return -1;
120        }
121
122        json_object_foreach(root, key, value) {
123                if (!strcmp(key, "rest")) {
[bdd8519]124                        if (parse_json_rest(cfg, value) < 0) {
125                                ret = -1;
126                                break;
127                        }
[866b6c5]128                        flags |= OG_SERVER_CFG_REST;
129                } else if (!strcmp(key, "wol")) {
[bdd8519]130                        if (parse_json_wol(cfg, value) < 0) {
131                                ret = -1;
132                                break;
133                        }
[866b6c5]134                        flags |= OG_SERVER_CFG_WOL;
135                } else if (!strcmp(key, "database")) {
[bdd8519]136                        if (parse_json_db(cfg, value) < 0) {
137                                ret = -1;
138                                break;
139                        }
[866b6c5]140                        flags |= OG_SERVER_CFG_DB;
141                } else {
142                        syslog(LOG_ERR, "unknown key `%s' in %s\n",
143                               key, filename);
144                        ret = -1;
145                }
146        }
147
[bdd8519]148        if (ret < 0)
149                json_decref(root);
150
[866b6c5]151        if ((flags & OG_SERVER_CFG_REST) &&
152            (flags & OG_SERVER_CFG_DB) &&
153            (flags & OG_SERVER_CFG_WOL)) {
154                ret = 0;
155        } else {
156                syslog(LOG_ERR, "Missing attributes in json file");
157                ret = -1;
158        }
159
[bdd8519]160        if (ret < 0)
161                json_decref(root);
162        else
163                cfg->json = root;
[866b6c5]164
165        return ret;
166}
167
168void from_json_to_legacy(struct og_server_cfg *cfg)
169{
[540cfb5]170        snprintf(servidoradm, sizeof(servidoradm), "%s", cfg->rest.ip);
171        snprintf(puerto, sizeof(puerto), "%s", cfg->rest.port);
172        snprintf(usuario, sizeof(usuario), "%s", cfg->db.user);
173        snprintf(pasguor, sizeof(pasguor), "%s", cfg->db.pass);
174        snprintf(datasource, sizeof(datasource), "%s", cfg->db.ip);
175        snprintf(catalog, sizeof(catalog), "%s", cfg->db.name);
176        snprintf(interface, sizeof(interface), "%s", cfg->wol.interface);
177        snprintf(auth_token, sizeof(auth_token), "%s", cfg->rest.api_token);
[0631b0e]178        snprintf(db_port, sizeof(db_port), "%u", cfg->db.port);
[866b6c5]179}
Note: See TracBrowser for help on using the repository browser.