mirror of
https://dev.iopsys.eu/bbf/icwmp.git
synced 2025-12-10 07:44:41 +01:00
Fix relative URI in GET request
This commit is contained in:
parent
5553a890ae
commit
9f20db9d6d
4 changed files with 67 additions and 15 deletions
|
|
@ -98,7 +98,7 @@ static int get_param_index(char *key)
|
|||
return -1;
|
||||
}
|
||||
|
||||
static void strip_lead_trail_char(char *str, char ch)
|
||||
void strip_lead_trail_char(char *str, char ch)
|
||||
{
|
||||
/* First remove leading strip-char */
|
||||
const char* first_valid = str;
|
||||
|
|
@ -366,9 +366,33 @@ int http_authentication_failure_resp(FILE *fp, const char *http_meth, const char
|
|||
return 1;
|
||||
}
|
||||
|
||||
static void get_relative_path(const char *uri, const char *req_host, char *req_path, size_t size)
|
||||
{
|
||||
if (uri == NULL || req_path == NULL)
|
||||
return;
|
||||
|
||||
memset(req_path, 0, size);
|
||||
if (req_host == NULL || strlen(req_host) == 0) {
|
||||
snprintf(req_path, size, "%s", uri);
|
||||
return;
|
||||
}
|
||||
|
||||
size_t host_len = strlen(req_host);
|
||||
if (strncmp(uri, req_host, host_len) == 0) {
|
||||
if (strlen(uri) == host_len) {
|
||||
snprintf(req_path, size, "/");
|
||||
} else {
|
||||
snprintf(req_path, size, "%s", uri + strlen(req_host));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
snprintf(req_path, size, "%s", uri);
|
||||
}
|
||||
|
||||
int validate_http_digest_auth(const char *http_meth, const char *uri, const char *hdr,
|
||||
const char *rlm, const char *usr, const char *psw,
|
||||
unsigned int timeout)
|
||||
unsigned int timeout, const char *req_host)
|
||||
{
|
||||
get_value_from_header(hdr);
|
||||
|
||||
|
|
@ -422,13 +446,22 @@ int validate_http_digest_auth(const char *http_meth, const char *uri, const char
|
|||
if (strlen(param[E_URI].value) == 0)
|
||||
return 0;
|
||||
|
||||
if (strncmp(param[E_URI].value, uri, strlen(uri)) != 0) {
|
||||
CWMP_LOG(ERROR, "Authentication failed, URI is not matched");
|
||||
CWMP_LOG(INFO, "Requested URI: (%s)", param[E_URI].value);
|
||||
char req_path[2049] = {0};
|
||||
get_relative_path(param[E_URI].value, req_host, req_path, sizeof(req_path));
|
||||
if (strlen(req_path) == 0)
|
||||
return 0;
|
||||
|
||||
CWMP_LOG(INFO, "Abs path: (%s)", req_path);
|
||||
if (strncmp(req_path, uri, strlen(uri)) != 0) {
|
||||
CWMP_LOG(ERROR, "Authentication failed, configured uri(%s), req path(%s) not matched", uri, req_path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((strcmp(param[E_QOP].value, "auth") != 0) && (strcmp(param[E_QOP].value, "") != 0))
|
||||
if ((strcmp(param[E_QOP].value, "auth") != 0) && (strcmp(param[E_QOP].value, "") != 0)) {
|
||||
CWMP_LOG(ERROR, "Authentication failed, due to qop value: (%s)", param[E_QOP].value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *tmp;
|
||||
unsigned long int nc_int = strtoul(param[E_NC].value, &tmp, 16);
|
||||
|
|
@ -442,12 +475,17 @@ int validate_http_digest_auth(const char *http_meth, const char *uri, const char
|
|||
char resp[MD5_HASH_HEX_LEN + 1];
|
||||
|
||||
get_digest_ha1("md5", usr, rlm, psw, param[E_NONCE].value, param[E_CNONCE].value, ha1, sizeof(ha1));
|
||||
get_digest_ha2(http_meth, uri, ha2, sizeof(ha2));
|
||||
get_digest_ha2(http_meth, param[E_URI].value, ha2, sizeof(ha2));
|
||||
get_digest_response(ha1, param[E_NONCE].value, param[E_NC].value, param[E_CNONCE].value,
|
||||
param[E_QOP].value, ha2, resp, sizeof(resp));
|
||||
|
||||
if (strcmp(resp, param[E_RESPONSE].value) != 0)
|
||||
if (strcmp(resp, param[E_RESPONSE].value) != 0) {
|
||||
CWMP_LOG(ERROR, "Authentication failed due to response, rec(%s) calc(%s)", param[E_RESPONSE].value, resp);
|
||||
CWMP_LOG(ERROR, "## received nonce:(%s) nc:(%s) usr:(%s)", param[E_NONCE].value, param[E_NC].value, usr);
|
||||
CWMP_LOG(ERROR, "## rlm:(%s) psw:(%s) meth:(%s)", rlm, psw, http_meth);
|
||||
CWMP_LOG(ERROR, "## cnonce:(%s)", param[E_CNONCE].value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,9 +16,10 @@
|
|||
extern char *nonce_key;
|
||||
|
||||
int get_nonce_key(void);
|
||||
void strip_lead_trail_char(char *str, char ch);
|
||||
int validate_http_digest_auth(const char *http_meth, const char *uri, const char *hdr,
|
||||
const char *rlm, const char *usr, const char *psw,
|
||||
unsigned int timeout);
|
||||
unsigned int timeout, const char *req_host);
|
||||
int http_authentication_failure_resp(FILE *fp, const char *http_meth, const char *uri,
|
||||
const char *rlm, const char *opq);
|
||||
|
||||
|
|
|
|||
16
src/http.c
16
src/http.c
|
|
@ -317,6 +317,7 @@ static void http_cr_new_client(int client, bool service_available)
|
|||
bool auth_digest_checked = false;
|
||||
bool method_is_get = false;
|
||||
bool internal_error = false;
|
||||
char request_host[2049] = {0};
|
||||
|
||||
char cr_http_get_head[HTTP_GET_HDR_LEN] = {0};
|
||||
|
||||
|
|
@ -333,6 +334,11 @@ static void http_cr_new_client(int client, bool service_available)
|
|||
}
|
||||
snprintf(cr_http_get_head, sizeof(cr_http_get_head), "GET %s HTTP/1.1", cwmp_main.conf.connection_request_path);
|
||||
while (fgets(buffer, sizeof(buffer), fp)) {
|
||||
if (buffer[0] == '\r' || buffer[0] == '\n') {
|
||||
/* end of http request (empty line) */
|
||||
break;
|
||||
}
|
||||
|
||||
if (strstr(buffer, "GET ") != NULL && strstr(buffer, "HTTP/1.1") != NULL) {
|
||||
// check if extra url parameter then ignore extra params
|
||||
int j = 0;
|
||||
|
|
@ -355,21 +361,23 @@ static void http_cr_new_client(int client, bool service_available)
|
|||
method_is_get = true;
|
||||
}
|
||||
|
||||
strip_lead_trail_char(buffer, '\n');
|
||||
strip_lead_trail_char(buffer, '\r');
|
||||
if (!strncasecmp(buffer, "Authorization: Digest ", strlen("Authorization: Digest "))) {
|
||||
auth_digest_checked = true;
|
||||
CWMP_STRNCPY(auth_digest_buffer, buffer, BUFSIZ);
|
||||
}
|
||||
|
||||
if (buffer[0] == '\r' || buffer[0] == '\n') {
|
||||
/* end of http request (empty line) */
|
||||
break;
|
||||
if (strncasecmp(buffer, "Host: ", strlen("Host: ")) == 0 && strlen(buffer) > strlen("Host: ")) {
|
||||
snprintf(request_host, sizeof(request_host), "http://%s", buffer + strlen("Host: "));
|
||||
}
|
||||
}
|
||||
if (!service_available || !method_is_get) {
|
||||
goto http_end;
|
||||
}
|
||||
|
||||
int auth_check = validate_http_digest_auth("GET", cwmp_main.conf.connection_request_path, auth_digest_buffer + strlen("Authorization: Digest "), REALM, username, password, 300);
|
||||
CWMP_LOG(INFO, "Received host: (%s)", request_host);
|
||||
int auth_check = validate_http_digest_auth("GET", cwmp_main.conf.connection_request_path, auth_digest_buffer + strlen("Authorization: Digest "), REALM, username, password, 300, request_host);
|
||||
if (auth_check == -1) { /* invalid nonce */
|
||||
internal_error = true;
|
||||
goto http_end;
|
||||
|
|
|
|||
11
src/rpc.c
11
src/rpc.c
|
|
@ -101,26 +101,31 @@ int xml_handle_message(struct session *session)
|
|||
}
|
||||
|
||||
c = (char *)mxmlGetElement(b);
|
||||
if (c == NULL) {
|
||||
CWMP_LOG(INFO, "Could not get element from received message");
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* convert QName to localPart, check that ns is the expected one */
|
||||
if (strchr(c, ':')) {
|
||||
char *tmp = strchr(c, ':');
|
||||
size_t ns_len = tmp - c;
|
||||
|
||||
if (strlen(ns.cwmp) != ns_len) {
|
||||
CWMP_LOG(INFO, "Invalid received message");
|
||||
CWMP_LOG(INFO, "Namespace length is not matched in string (%s) and expected (%s)", c, ns.cwmp);
|
||||
session->fault_code = FAULT_CPE_REQUEST_DENIED;
|
||||
goto fault;
|
||||
}
|
||||
|
||||
if (strncmp(ns.cwmp, c, ns_len)) {
|
||||
CWMP_LOG(INFO, "Invalid received message");
|
||||
CWMP_LOG(INFO, "Namespace in string (%s) is not the expected (%s) one", c, ns.cwmp);
|
||||
session->fault_code = FAULT_CPE_REQUEST_DENIED;
|
||||
goto fault;
|
||||
}
|
||||
|
||||
c = tmp + 1;
|
||||
} else {
|
||||
CWMP_LOG(INFO, "Invalid received message");
|
||||
CWMP_LOG(INFO, "Can not convert QName to local part with received string (%s)", c);
|
||||
session->fault_code = FAULT_CPE_REQUEST_DENIED;
|
||||
goto fault;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue