107 lines
3.3 KiB
C
107 lines
3.3 KiB
C
#include "include/conf.h"
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#include "include/proto.h"
|
|
#include "include/commands.h"
|
|
|
|
#include "server/include/def.h"
|
|
#include "server/include/auth.h"
|
|
#include "server/include/proto.h"
|
|
|
|
#define DC_CMD_COMMAND_USAGE() \
|
|
dp_logf(logger, DP_LOG_ERROR, DC_COMMANDS_LOG "/command", \
|
|
"Usage: %s " \
|
|
"<trigger|teardown|deploy|rollback|cleanup|restart|sysadmin|logs>" \
|
|
" <is_unsafe = 1|0> <id> <domain> <key> <secret> <timestamp>", \
|
|
argv[0])
|
|
|
|
typedef struct {
|
|
const char *name;
|
|
dp_DeployCommand command;
|
|
} dc_DeployCommandMap;
|
|
|
|
int dc_cmd_command(SSL *ssl, int argc, const char *argv[], dp_Logger *logger) {
|
|
if (!ssl || argc < 1 || !logger) {
|
|
return -1;
|
|
}
|
|
|
|
if (argc < 8) {
|
|
DC_CMD_COMMAND_USAGE();
|
|
return 0;
|
|
}
|
|
|
|
static const dc_DeployCommandMap commands[] = {
|
|
{"trigger", dp_DeployCommand_trigger},
|
|
{"teardown", dp_DeployCommand_teardown},
|
|
{"deploy", dp_DeployCommand_deploy},
|
|
{"rollback", dp_DeployCommand_rollback},
|
|
{"cleanup", dp_DeployCommand_cleanup},
|
|
{"restart", dp_DeployCommand_restart},
|
|
{"sysadmin", dp_DeployCommand_sysadmin},
|
|
{"logs", dp_DeployCommand_logs},
|
|
};
|
|
|
|
dp_DeployCommand command = 0;
|
|
bool found = false;
|
|
for (size_t idx = 0; idx < sizeof(commands) / sizeof(commands[0]); ++idx) {
|
|
if (strcmp(commands[idx].name, argv[1]) == 0) {
|
|
command = commands[idx].command;
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!found) {
|
|
dp_logf(logger, DP_LOG_ERROR, DC_COMMANDS_LOG "/command",
|
|
"Unknown command type: %s", argv[0]);
|
|
DC_CMD_COMMAND_USAGE();
|
|
return -1;
|
|
}
|
|
|
|
const bool is_unsafe = (argv[2][0] == '1' ? true : false);
|
|
|
|
if (!dp_isnumber(argv[3])) {
|
|
dp_logf(logger, DP_LOG_ERROR, DC_COMMANDS_LOG "/command",
|
|
"Invalid ID: %s", argv[2]);
|
|
return -1;
|
|
}
|
|
const uint64_t tid = dp_str2u64(argv[3]);
|
|
|
|
const char *domain = argv[4];
|
|
const size_t domain_len = strlen(domain);
|
|
if (domain_len > 255) {
|
|
dp_logf(logger, DP_LOG_ERROR, DC_COMMANDS_LOG "/command",
|
|
"Domain '%s' too long", argv[4]);
|
|
return -1;
|
|
}
|
|
|
|
const char *key = argv[5];
|
|
const char *secret = argv[6];
|
|
|
|
if (!dp_isnumber(argv[7])) {
|
|
dp_logf(logger, DP_LOG_ERROR, DC_COMMANDS_LOG "/command",
|
|
"Invalid timestamp: %s", argv[7]);
|
|
return -1;
|
|
}
|
|
const uint64_t timestamp = dp_str2u64(argv[7]);
|
|
|
|
/* Generate token */
|
|
uint8_t token[DP_AUTH_TOKEN_SIZE] = {0};
|
|
|
|
if (!dp_auth_gen_token(token, timestamp, (const uint8_t *)secret)) {
|
|
dp_log(logger, DP_LOG_ERROR, DC_COMMANDS_LOG "/command",
|
|
"Failed to generate an authentication token");
|
|
return -1;
|
|
}
|
|
|
|
dp_logf(logger, DP_LOG_INFO, DC_COMMANDS_LOG "/command",
|
|
"Running command '%s' on '%s'", argv[1], domain);
|
|
|
|
if (!dc_proto_command(ssl, logger, command, is_unsafe, tid,
|
|
(uint8_t)domain_len, domain, (const uint8_t *)key,
|
|
token, true)) {
|
|
return -1;
|
|
}
|
|
return 8;
|
|
}
|