mirror of https://git.48k.eu/ogserver
core: add X-Sequence header support
Add non-standard HTTP header "X-Sequence" to the header section of requests (og_send_request) sent to a connected client. Define a starting sequence number when creating a new instance of struct og_client inside og_server_accept_cb. This sequence number is incremented by one for each outgoing request from ogServer. This sequence number is checked when receiving a response from a connected client, if they do not match the connection is dropped. Use sequence 0 for out-of-band commands (reboot, poweroff, stop). Any client response with header "X-Sequence: 0" bypasses sequence check.master v1.2.2
parent
92f83c0385
commit
d2c19ef13d
15
src/core.c
15
src/core.c
|
@ -160,6 +160,7 @@ enum og_agent_state {
|
|||
|
||||
static int og_agent_state_recv_hdr_rest(struct og_client *cli)
|
||||
{
|
||||
uint32_t seq;
|
||||
char *ptr;
|
||||
|
||||
ptr = strstr(cli->buf, "\r\n\r\n");
|
||||
|
@ -176,6 +177,20 @@ static int og_agent_state_recv_hdr_rest(struct og_client *cli)
|
|||
cli->msg_len += cli->content_length;
|
||||
}
|
||||
|
||||
ptr = strstr(cli->buf, "X-Sequence: ");
|
||||
if (ptr) {
|
||||
if (sscanf(ptr, "X-Sequence: %i[^\r\n]", &seq) != 1) {
|
||||
syslog(LOG_ERR, "Invalid sequence value from client %s. Payload:\n%s",
|
||||
inet_ntoa(cli->addr.sin_addr), cli->buf);
|
||||
return -1;
|
||||
}
|
||||
if (cli->seq != 0 && cli->seq != seq) {
|
||||
syslog(LOG_ERR, "Unexpected sequence %u from client %s, expecting %u.",
|
||||
seq, inet_ntoa(cli->addr.sin_addr), cli->seq);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
22
src/rest.c
22
src/rest.c
|
@ -296,6 +296,7 @@ int og_send_request(enum og_rest_method method, enum og_cmd_type type,
|
|||
const char *uri;
|
||||
unsigned int i;
|
||||
int client_sd;
|
||||
bool has_seq;
|
||||
|
||||
if (method == OG_METHOD_GET)
|
||||
snprintf(method_str, 5, "GET");
|
||||
|
@ -312,9 +313,17 @@ int og_send_request(enum og_rest_method method, enum og_cmd_type type,
|
|||
JSON_COMPACT);
|
||||
|
||||
uri = og_cmd_to_uri[type];
|
||||
snprintf(buf, OG_MSG_REQUEST_MAXLEN,
|
||||
"%s /%s HTTP/1.1\r\nContent-Length: %d\r\n%s\r\n\r\n%s",
|
||||
method_str, uri, content_length, content_type, content);
|
||||
|
||||
switch (type) {
|
||||
case OG_CMD_POWEROFF:
|
||||
case OG_CMD_REBOOT:
|
||||
case OG_CMD_STOP:
|
||||
has_seq = false;
|
||||
break;
|
||||
default:
|
||||
has_seq = true;
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < params->ips_array_len; i++) {
|
||||
cli = og_client_find(params->ips_array[i]);
|
||||
|
@ -331,6 +340,13 @@ int og_send_request(enum og_rest_method method, enum og_cmd_type type,
|
|||
continue;
|
||||
}
|
||||
|
||||
if (++cli->seq == 0)
|
||||
cli->seq++;
|
||||
|
||||
snprintf(buf, OG_MSG_REQUEST_MAXLEN,
|
||||
"%s /%s HTTP/1.1\r\nContent-Length: %d\r\nX-Sequence: %u\r\n%s\r\n\r\n%s",
|
||||
method_str, uri, content_length, has_seq ? cli->seq : 0, content_type, content);
|
||||
|
||||
if (send(client_sd, buf, strlen(buf), 0) < 0)
|
||||
continue;
|
||||
|
||||
|
|
|
@ -68,6 +68,7 @@ struct og_client {
|
|||
enum og_cmd_result last_cmd_result;
|
||||
bool autorun;
|
||||
uint32_t speed;
|
||||
uint32_t seq;
|
||||
const char *shell_output;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue