kore

An easy to use, scalable and secure web application framework for writing web APIs in C.
Commits | Files | Refs | README | LICENSE | git clone https://git.kore.io/kore.git

validator.c (3214B)



      1 /*
      2  * Copyright (c) 2013-2022 Joris Vink <joris@coders.se>
      3  *
      4  * Permission to use, copy, modify, and distribute this software for any
      5  * purpose with or without fee is hereby granted, provided that the above
      6  * copyright notice and this permission notice appear in all copies.
      7  *
      8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
      9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     15  */
     16 
     17 #include <sys/types.h>
     18 
     19 #include "kore.h"
     20 
     21 TAILQ_HEAD(, kore_validator)		validators;
     22 
     23 void
     24 kore_validator_init(void)
     25 {
     26 	TAILQ_INIT(&validators);
     27 }
     28 
     29 int
     30 kore_validator_add(const char *name, u_int8_t type, const char *arg)
     31 {
     32 	int				ret;
     33 	struct kore_validator		*val;
     34 
     35 	val = kore_malloc(sizeof(*val));
     36 	val->type = type;
     37 
     38 	switch (val->type) {
     39 	case KORE_VALIDATOR_TYPE_REGEX:
     40 		ret = regcomp(&(val->rctx), arg, REG_EXTENDED | REG_NOSUB);
     41 		if (ret) {
     42 			kore_free(val);
     43 			kore_log(LOG_NOTICE,
     44 			    "validator %s has bad regex %s (%d)",
     45 			    name, arg, ret);
     46 			return (KORE_RESULT_ERROR);
     47 		}
     48 		break;
     49 	case KORE_VALIDATOR_TYPE_FUNCTION:
     50 		val->rcall = kore_runtime_getcall(arg);
     51 		if (val->rcall == NULL) {
     52 			kore_free(val);
     53 			kore_log(LOG_NOTICE,
     54 			    "validator %s has undefined callback %s",
     55 			    name, arg);
     56 			return (KORE_RESULT_ERROR);
     57 		}
     58 		break;
     59 	default:
     60 		kore_free(val);
     61 		return (KORE_RESULT_ERROR);
     62 	}
     63 
     64 	val->arg = kore_strdup(arg);
     65 	val->name = kore_strdup(name);
     66 	TAILQ_INSERT_TAIL(&validators, val, list);
     67 
     68 	return (KORE_RESULT_OK);
     69 }
     70 
     71 int
     72 kore_validator_run(struct http_request *req, const char *name, char *data)
     73 {
     74 	struct kore_validator		*val;
     75 
     76 	TAILQ_FOREACH(val, &validators, list) {
     77 		if (strcmp(val->name, name))
     78 			continue;
     79 
     80 		return (kore_validator_check(req, val, data));
     81 	}
     82 
     83 	return (KORE_RESULT_ERROR);
     84 }
     85 
     86 int
     87 kore_validator_check(struct http_request *req, struct kore_validator *val,
     88     const void *data)
     89 {
     90 	int		r;
     91 
     92 	switch (val->type) {
     93 	case KORE_VALIDATOR_TYPE_REGEX:
     94 		if (!regexec(&(val->rctx), data, 0, NULL, 0))
     95 			r = KORE_RESULT_OK;
     96 		else
     97 			r = KORE_RESULT_ERROR;
     98 		break;
     99 	case KORE_VALIDATOR_TYPE_FUNCTION:
    100 		r = kore_runtime_validator(val->rcall, req, data);
    101 		break;
    102 	default:
    103 		r = KORE_RESULT_ERROR;
    104 		kore_log(LOG_NOTICE, "invalid type %d for validator %s",
    105 		    val->type, val->name);
    106 		break;
    107 	}
    108 
    109 	return (r);
    110 }
    111 
    112 void
    113 kore_validator_reload(void)
    114 {
    115 	struct kore_validator		*val;
    116 
    117 	TAILQ_FOREACH(val, &validators, list) {
    118 		if (val->type != KORE_VALIDATOR_TYPE_FUNCTION)
    119 			continue;
    120 
    121 		kore_free(val->rcall);
    122 		val->rcall = kore_runtime_getcall(val->arg);
    123 		if (val->rcall == NULL)
    124 			fatal("no function for validator %s found", val->arg);
    125 	}
    126 }
    127 
    128 struct kore_validator *
    129 kore_validator_lookup(const char *name)
    130 {
    131 	struct kore_validator		*val;
    132 
    133 	TAILQ_FOREACH(val, &validators, list) {
    134 		if (!strcmp(val->name, name))
    135 			return (val);
    136 	}
    137 
    138 	return (NULL);
    139 }