diff --git a/apps/restconf/restconf_api_evhtp.c b/apps/restconf/restconf_api_evhtp.c index 753a2de7..390265ca 100644 --- a/apps/restconf/restconf_api_evhtp.c +++ b/apps/restconf/restconf_api_evhtp.c @@ -131,23 +131,26 @@ restconf_reply_send(void *req0, { evhtp_request_t *req = (evhtp_request_t *)req0; int retval = -1; - evhtp_connection_t *conn; struct evbuffer *eb = NULL; - const char *reason_phrase; + const char *reason_phrase; req->status = code; if ((reason_phrase = restconf_code2reason(code)) == NULL) reason_phrase=""; -#if 1 /* XXX remove status header för evhtp? */ +#if 0 /* XXX remove status header för evhtp? */ if (restconf_reply_header(req, "Status", "%d %s", code, reason_phrase) < 0) goto done; #endif -#if 1 /* Optional? */ - if ((conn = evhtp_request_get_connection(req)) == NULL){ - clicon_err(OE_DAEMON, EFAULT, "evhtp_request_get_connection"); - goto done; +#if 0 /* Optional? */ + { + evhtp_connection_t *conn; + + if ((conn = evhtp_request_get_connection(req)) == NULL){ + clicon_err(OE_DAEMON, EFAULT, "evhtp_request_get_connection"); + goto done; + } + htp_sslutil_add_xheaders(req->headers_out, conn->ssl, HTP_SSLUTILS_XHDR_ALL); } - htp_sslutil_add_xheaders(req->headers_out, conn->ssl, HTP_SSLUTILS_XHDR_ALL); #endif /* If body, add a content-length header */ @@ -190,10 +193,20 @@ restconf_get_indata(void *req0) { evhtp_request_t *req = (evhtp_request_t *)req0; cbuf *cb = NULL; - + size_t len; + unsigned char *buf; + if ((cb = cbuf_new()) == NULL) return NULL; - if (evbuffer_get_length(req->buffer_in)) - cprintf(cb, "%s", evbuffer_pullup(req->buffer_in, -1)); + len = evbuffer_get_length(req->buffer_in); + if (len > 0){ + if ((buf = evbuffer_pullup(req->buffer_in, len)) == NULL){ + clicon_err(OE_CFG, errno, "evbuffer_pullup"); + return NULL; + } + /* Note the pullup may not be null-terminated */ + cbuf_append_buf(cb, buf, len); + } + return cb; } diff --git a/apps/restconf/restconf_main_evhtp.c b/apps/restconf/restconf_main_evhtp.c index b42f39eb..8519ddb2 100644 --- a/apps/restconf/restconf_main_evhtp.c +++ b/apps/restconf/restconf_main_evhtp.c @@ -78,10 +78,11 @@ #include "restconf_lib.h" /* generic shared with plugins */ #include "restconf_handle.h" #include "restconf_api.h" /* generic not shared with plugins */ +#include "restconf_err.h" #include "restconf_root.h" /* Command line options to be passed to getopt(3) */ -#define RESTCONF_OPTS "hD:f:l:p:d:y:a:u:o:P:c:k:" +#define RESTCONF_OPTS "hD:f:l:p:d:y:a:u:o:P:s" /* Need global variable to for signal handler XXX */ static clicon_handle _CLICON_HANDLE = NULL; @@ -248,7 +249,8 @@ convert_fcgi(evhtp_header_t *hdr, * @param[in] h Clicon handle * @param[in] req Evhtp request struct * @param[out] qvec Query parameters, ie the ?=&= stuff - * @retval 0 OK + * @retval 1 OK continue + * @retval 0 Fail, dont continue * @retval -1 Error * The following parameters are set: * QUERY_STRING @@ -293,16 +295,30 @@ evhtp_params_set(clicon_handle h, goto done; if (restconf_param_set(h, "REQUEST_URI", path->full) < 0) goto done; - if (restconf_param_set(h, "HTTPS", "https") < 0) /* some string or NULL */ - goto done; + clicon_debug(1, "%s proto:%d", __FUNCTION__, req->proto); + if (req->proto != EVHTP_PROTO_10 && + req->proto != EVHTP_PROTO_11){ + if (restconf_badrequest(h, req) < 0) + goto done; + goto fail; + } + clicon_debug(1, "%s conn->ssl:%d", __FUNCTION__, req->conn->ssl?1:0); + if (req->conn->ssl != NULL){ + if (restconf_param_set(h, "HTTPS", "https") < 0) /* some string or NULL */ + goto done; + } + /* Translate all http headers by capitalizing, prepend w HTTP_ and - -> _ * Example: Host -> HTTP_HOST */ if (evhtp_headers_for_each(req->headers_in, convert_fcgi, h) < 0) goto done; - retval = 0; + retval = 1; done: return retval; + fail: + retval = 0; + goto done; } static int @@ -368,7 +384,8 @@ static void cx_path_wellknown(evhtp_request_t *req, void *arg) { - clicon_handle h = arg; + clicon_handle h = arg; + int ret; clicon_debug(1, "------------"); /* input debug */ @@ -377,12 +394,13 @@ cx_path_wellknown(evhtp_request_t *req, /* get accepted connection */ /* set fcgi-like paramaters (ignore query vector) */ - if (evhtp_params_set(h, req, NULL) < 0) + if ((ret = evhtp_params_set(h, req, NULL)) < 0) goto done; - /* call generic function */ - if (api_well_known(h, req) < 0) - goto done; - + if (ret == 1){ + /* call generic function */ + if (api_well_known(h, req) < 0) + goto done; + } /* Clear (fcgi) paramaters from this request */ if (restconf_param_del_all(h) < 0) goto done; @@ -398,6 +416,7 @@ cx_path_restconf(evhtp_request_t *req, void *arg) { clicon_handle h = arg; + int ret; cvec *qvec = NULL; clicon_debug(1, "------------"); @@ -411,11 +430,13 @@ cx_path_restconf(evhtp_request_t *req, goto done; } /* set fcgi-like paramaters (ignore query vector) */ - if (evhtp_params_set(h, req, qvec) < 0) - goto done; - /* call generic function */ - if (api_root_restconf(h, req, qvec) < 0) + if ((ret = evhtp_params_set(h, req, qvec)) < 0) goto done; + if (ret == 1){ + /* call generic function */ + if (api_root_restconf(h, req, qvec) < 0) + goto done; + } /* Clear (fcgi) paramaters from this request */ if (restconf_param_del_all(h) < 0) @@ -424,6 +445,52 @@ cx_path_restconf(evhtp_request_t *req, return; /* void */ } +/*! Get Server cert info + * @param[out] ssl_config + */ +static int +get_servercerts(evhtp_ssl_cfg_t *ssl_config, + const char *pki_dir, + const char *ssl_server_cert) +{ + int retval = -1; + cbuf *cb = NULL; + struct stat f_stat; + + if (ssl_config == NULL){ + clicon_err(OE_CFG, EINVAL, "ssl_config is NULL"); + goto done; + } + if ((cb = cbuf_new()) == NULL){ + clicon_err(OE_UNIX, errno, "cbuf_new"); + goto done; + } + cprintf(cb, "%s/%s-crt.pem", pki_dir, ssl_server_cert); + if ((ssl_config->pemfile = strdup(cbuf_get(cb))) == NULL){ + clicon_err(OE_UNIX, errno, "strdup"); + goto done; + } + if (stat(ssl_config->pemfile, &f_stat) != 0) { + clicon_err(OE_FATAL, errno, "Cannot load SSL cert '%s'", ssl_config->pemfile); + goto done; + } + cbuf_reset(cb); + cprintf(cb, "%s/%s-key.pem", pki_dir, ssl_server_cert); + if ((ssl_config->privfile = strdup(cbuf_get(cb))) == NULL){ + clicon_err(OE_UNIX, errno, "strdup"); + goto done; + } + if (stat(ssl_config->privfile, &f_stat) != 0) { + clicon_err(OE_FATAL, errno, "Cannot load SSL key '%s'", ssl_config->privfile); + goto done; + } + retval = 0; + done: + if (cb) + cbuf_free(cb); + return retval; +} + /*! Usage help routine * @param[in] argv0 command line * @param[in] h Clicon handle @@ -445,9 +512,8 @@ usage(clicon_handle h, "\t-a UNIX|IPv4|IPv6 Internal backend socket family\n" "\t-u \t Internal socket domain path or IP addr (see -a)\n" "\t-o \"