proxy NONE
+COMMAND -- cr-response (OpenVPN 2.5 or higher)
+-------------------------------------------------
+Provides support for sending responses a challenge/response
+query via INFOMSG,CR_TEXT. The response should be base64 encoded:
+
+ cr-response SGFsbG8gV2VsdCE=
+
+The document is intended to be used after the client received a
+CR_TEXT challenge (see send-pending-auth section). The answer is
+the answer to the challenge and depends on the challenge itself
+for a TOTP challenge this would the number encoded as base64 or
+just a string for a challenge like "what day is it today?".
+
+
COMMAND -- pk-sig (OpenVPN 2.5 or higher, management version > 1)
COMMAND -- rsa-sig (OpenVPN 2.3 or higher, management version <= 1)
-----------------------------------------------------------------
return ret;
}
+/**
+ * This method sends a custom control channel message
+ *
+ * This will write the control message
+ *
+ * command parm1,parm2,..
+ * .
+ * to the control channel.
+ *
+ * @param arg The context struct
+ * @param command The command being sent
+ * @param parameters the parameters to the command
+ * @return if sending was successful
+ */
+static bool
+management_callback_send_cc_message(void *arg,
+ const char *command,
+ const char *parameters)
+{
+ struct context *c = (struct context *) arg;
+ size_t len = strlen(command) + 1 + sizeof(parameters) + 1;
+ if (len > PUSH_BUNDLE_SIZE)
+ {
+ return false;
+ }
+
+ struct gc_arena gc = gc_new();
+ struct buffer buf = alloc_buf_gc(len, &gc);
+ ASSERT(buf_printf(&buf, "%s", command));
+ if (parameters)
+ {
+ ASSERT(buf_printf(&buf, ",%s", parameters));
+ }
+ bool status = send_control_channel_string(c, BSTR(&buf), D_PUSH);
+
+ gc_free(&gc);
+ return status;
+}
static bool
management_callback_remote_cmd(void *arg, const char **p)
cb.show_net = management_show_net_callback;
cb.proxy_cmd = management_callback_proxy_cmd;
cb.remote_cmd = management_callback_remote_cmd;
+ cb.send_cc_message = management_callback_send_cc_message;
#ifdef TARGET_ANDROID
cb.network_change = management_callback_network_change;
#endif
msg(M_CLIENT, "auth-retry t : Auth failure retry mode (none,interact,nointeract).");
msg(M_CLIENT, "bytecount n : Show bytes in/out, update every n secs (0=off).");
msg(M_CLIENT, "echo [on|off] [N|all] : Like log, but only show messages in echo buffer.");
+ msg(M_CLIENT, "cr-response response : Send a challenge response answer via CR_RESPONSE to server");
msg(M_CLIENT, "exit|quit : Close management session.");
msg(M_CLIENT, "forget-passwords : Forget passwords entered so far.");
msg(M_CLIENT, "help : Print this message.");
}
}
+static void
+man_send_cc_message(struct management *man, const char *message, const char *parameters)
+{
+ if (man->persist.callback.send_cc_message)
+ {
+ const bool status = (*man->persist.callback.send_cc_message)
+ (man->persist.callback.arg, message, parameters);
+ if (status)
+ {
+ msg(M_CLIENT, "SUCCESS: command succeeded");
+ }
+ else
+ {
+ msg(M_CLIENT, "ERROR: command failed");
+ }
+ }
+ else
+ {
+ msg(M_CLIENT, "ERROR: This command is not supported by the current daemon mode");
+ }
+}
#ifdef ENABLE_PKCS11
static void
}
#define MN_AT_LEAST (1<<0)
-
+/**
+ * Checks if the correct number of arguments to a management command are present
+ * and otherwise prints an error and returns false.
+ *
+ * @param p pointer to the parameter array
+ * @param n number of arguments required
+ * @param flags if MN_AT_LEAST require at least n parameters and not exactly n
+ * @return Return whether p has n (or at least n) parameters
+ */
static bool
man_need(struct management *man, const char **p, const int n, unsigned int flags)
{
man_query_need_str(man, p[1], p[2]);
}
}
+ else if (streq(p[0], "cr-response"))
+ {
+ if (man_need(man, p, 1, 0))
+ {
+ man_send_cc_message(man, "CR_RESPONSE", p[1]);
+ }
+ }
else if (streq(p[0], "net"))
{
man_net(man);
int (*kill_by_addr) (void *arg, const in_addr_t addr, const int port);
void (*delete_event) (void *arg, event_t event);
int (*n_clients) (void *arg);
+ bool (*send_cc_message) (void *arg, const char *message, const char *parameter);
#ifdef MANAGEMENT_DEF_AUTH
bool (*kill_by_cid)(void *arg, const unsigned long cid, const char *kill_msg);
bool (*client_auth) (void *arg,