Interworking: Add ctrl_iface commands for managing credentials
New wpa_cli commands list_creds, add_cred, remove_cred, and set_cred can now be used to manage credentials similarly to the commands used with network blocks. Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
parent
f2c207515a
commit
d94c9ee6ad
4 changed files with 276 additions and 0 deletions
|
@ -2272,6 +2272,74 @@ int wpa_config_set_cred(struct wpa_cred *cred, const char *var,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct wpa_cred * wpa_config_get_cred(struct wpa_config *config, int id)
|
||||||
|
{
|
||||||
|
struct wpa_cred *cred;
|
||||||
|
|
||||||
|
cred = config->cred;
|
||||||
|
while (cred) {
|
||||||
|
if (id == cred->id)
|
||||||
|
break;
|
||||||
|
cred = cred->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cred;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct wpa_cred * wpa_config_add_cred(struct wpa_config *config)
|
||||||
|
{
|
||||||
|
int id;
|
||||||
|
struct wpa_cred *cred, *last = NULL;
|
||||||
|
|
||||||
|
id = -1;
|
||||||
|
cred = config->cred;
|
||||||
|
while (cred) {
|
||||||
|
if (cred->id > id)
|
||||||
|
id = cred->id;
|
||||||
|
last = cred;
|
||||||
|
cred = cred->next;
|
||||||
|
}
|
||||||
|
id++;
|
||||||
|
|
||||||
|
cred = os_zalloc(sizeof(*cred));
|
||||||
|
if (cred == NULL)
|
||||||
|
return NULL;
|
||||||
|
cred->id = id;
|
||||||
|
if (last)
|
||||||
|
last->next = cred;
|
||||||
|
else
|
||||||
|
config->cred = cred;
|
||||||
|
|
||||||
|
return cred;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int wpa_config_remove_cred(struct wpa_config *config, int id)
|
||||||
|
{
|
||||||
|
struct wpa_cred *cred, *prev = NULL;
|
||||||
|
|
||||||
|
cred = config->cred;
|
||||||
|
while (cred) {
|
||||||
|
if (id == cred->id)
|
||||||
|
break;
|
||||||
|
prev = cred;
|
||||||
|
cred = cred->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cred == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (prev)
|
||||||
|
prev->next = cred->next;
|
||||||
|
else
|
||||||
|
config->cred = cred->next;
|
||||||
|
|
||||||
|
wpa_config_free_cred(cred);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifndef CONFIG_NO_CONFIG_BLOBS
|
#ifndef CONFIG_NO_CONFIG_BLOBS
|
||||||
/**
|
/**
|
||||||
* wpa_config_get_blob - Get a named configuration blob
|
* wpa_config_get_blob - Get a named configuration blob
|
||||||
|
|
|
@ -547,6 +547,9 @@ void wpa_config_set_blob(struct wpa_config *config,
|
||||||
void wpa_config_free_blob(struct wpa_config_blob *blob);
|
void wpa_config_free_blob(struct wpa_config_blob *blob);
|
||||||
int wpa_config_remove_blob(struct wpa_config *config, const char *name);
|
int wpa_config_remove_blob(struct wpa_config *config, const char *name);
|
||||||
|
|
||||||
|
struct wpa_cred * wpa_config_get_cred(struct wpa_config *config, int id);
|
||||||
|
struct wpa_cred * wpa_config_add_cred(struct wpa_config *config);
|
||||||
|
int wpa_config_remove_cred(struct wpa_config *config, int id);
|
||||||
void wpa_config_free_cred(struct wpa_cred *cred);
|
void wpa_config_free_cred(struct wpa_cred *cred);
|
||||||
int wpa_config_set_cred(struct wpa_cred *cred, const char *var,
|
int wpa_config_set_cred(struct wpa_cred *cred, const char *var,
|
||||||
const char *value, int line);
|
const char *value, int line);
|
||||||
|
|
|
@ -1897,6 +1897,132 @@ static int wpa_supplicant_ctrl_iface_get_network(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int wpa_supplicant_ctrl_iface_list_creds(struct wpa_supplicant *wpa_s,
|
||||||
|
char *buf, size_t buflen)
|
||||||
|
{
|
||||||
|
char *pos, *end;
|
||||||
|
struct wpa_cred *cred;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
pos = buf;
|
||||||
|
end = buf + buflen;
|
||||||
|
ret = os_snprintf(pos, end - pos,
|
||||||
|
"cred id / realm / username / domain / imsi\n");
|
||||||
|
if (ret < 0 || ret >= end - pos)
|
||||||
|
return pos - buf;
|
||||||
|
pos += ret;
|
||||||
|
|
||||||
|
cred = wpa_s->conf->cred;
|
||||||
|
while (cred) {
|
||||||
|
ret = os_snprintf(pos, end - pos, "%d\t%s\t%s\t%s\t%s\n",
|
||||||
|
cred->id, cred->realm ? cred->realm : "",
|
||||||
|
cred->username ? cred->username : "",
|
||||||
|
cred->domain ? cred->domain : "",
|
||||||
|
cred->imsi ? cred->imsi : "");
|
||||||
|
if (ret < 0 || ret >= end - pos)
|
||||||
|
return pos - buf;
|
||||||
|
pos += ret;
|
||||||
|
|
||||||
|
cred = cred->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pos - buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int wpa_supplicant_ctrl_iface_add_cred(struct wpa_supplicant *wpa_s,
|
||||||
|
char *buf, size_t buflen)
|
||||||
|
{
|
||||||
|
struct wpa_cred *cred;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG, "CTRL_IFACE: ADD_CRED");
|
||||||
|
|
||||||
|
cred = wpa_config_add_cred(wpa_s->conf);
|
||||||
|
if (cred == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
ret = os_snprintf(buf, buflen, "%d\n", cred->id);
|
||||||
|
if (ret < 0 || (size_t) ret >= buflen)
|
||||||
|
return -1;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int wpa_supplicant_ctrl_iface_remove_cred(struct wpa_supplicant *wpa_s,
|
||||||
|
char *cmd)
|
||||||
|
{
|
||||||
|
int id;
|
||||||
|
struct wpa_cred *cred;
|
||||||
|
|
||||||
|
/* cmd: "<cred id>" or "all" */
|
||||||
|
if (os_strcmp(cmd, "all") == 0) {
|
||||||
|
wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_CRED all");
|
||||||
|
cred = wpa_s->conf->cred;
|
||||||
|
while (cred) {
|
||||||
|
id = cred->id;
|
||||||
|
cred = cred->next;
|
||||||
|
wpa_config_remove_cred(wpa_s->conf, id);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
id = atoi(cmd);
|
||||||
|
wpa_printf(MSG_DEBUG, "CTRL_IFACE: REMOVE_CRED id=%d", id);
|
||||||
|
|
||||||
|
cred = wpa_config_get_cred(wpa_s->conf, id);
|
||||||
|
if (cred == NULL ||
|
||||||
|
wpa_config_remove_cred(wpa_s->conf, id) < 0) {
|
||||||
|
wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find cred id=%d",
|
||||||
|
id);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int wpa_supplicant_ctrl_iface_set_cred(struct wpa_supplicant *wpa_s,
|
||||||
|
char *cmd)
|
||||||
|
{
|
||||||
|
int id;
|
||||||
|
struct wpa_cred *cred;
|
||||||
|
char *name, *value;
|
||||||
|
|
||||||
|
/* cmd: "<cred id> <variable name> <value>" */
|
||||||
|
name = os_strchr(cmd, ' ');
|
||||||
|
if (name == NULL)
|
||||||
|
return -1;
|
||||||
|
*name++ = '\0';
|
||||||
|
|
||||||
|
value = os_strchr(name, ' ');
|
||||||
|
if (value == NULL)
|
||||||
|
return -1;
|
||||||
|
*value++ = '\0';
|
||||||
|
|
||||||
|
id = atoi(cmd);
|
||||||
|
wpa_printf(MSG_DEBUG, "CTRL_IFACE: SET_CRED id=%d name='%s'",
|
||||||
|
id, name);
|
||||||
|
wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: value",
|
||||||
|
(u8 *) value, os_strlen(value));
|
||||||
|
|
||||||
|
cred = wpa_config_get_cred(wpa_s->conf, id);
|
||||||
|
if (cred == NULL) {
|
||||||
|
wpa_printf(MSG_DEBUG, "CTRL_IFACE: Could not find cred id=%d",
|
||||||
|
id);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wpa_config_set_cred(cred, name, value, 0) < 0) {
|
||||||
|
wpa_printf(MSG_DEBUG, "CTRL_IFACE: Failed to set cred "
|
||||||
|
"variable '%s'", name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifndef CONFIG_NO_CONFIG_WRITE
|
#ifndef CONFIG_NO_CONFIG_WRITE
|
||||||
static int wpa_supplicant_ctrl_iface_save_config(struct wpa_supplicant *wpa_s)
|
static int wpa_supplicant_ctrl_iface_save_config(struct wpa_supplicant *wpa_s)
|
||||||
{
|
{
|
||||||
|
@ -3801,6 +3927,18 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
|
||||||
} else if (os_strncmp(buf, "GET_NETWORK ", 12) == 0) {
|
} else if (os_strncmp(buf, "GET_NETWORK ", 12) == 0) {
|
||||||
reply_len = wpa_supplicant_ctrl_iface_get_network(
|
reply_len = wpa_supplicant_ctrl_iface_get_network(
|
||||||
wpa_s, buf + 12, reply, reply_size);
|
wpa_s, buf + 12, reply, reply_size);
|
||||||
|
} else if (os_strcmp(buf, "LIST_CREDS") == 0) {
|
||||||
|
reply_len = wpa_supplicant_ctrl_iface_list_creds(
|
||||||
|
wpa_s, reply, reply_size);
|
||||||
|
} else if (os_strcmp(buf, "ADD_CRED") == 0) {
|
||||||
|
reply_len = wpa_supplicant_ctrl_iface_add_cred(
|
||||||
|
wpa_s, reply, reply_size);
|
||||||
|
} else if (os_strncmp(buf, "REMOVE_CRED ", 12) == 0) {
|
||||||
|
if (wpa_supplicant_ctrl_iface_remove_cred(wpa_s, buf + 12))
|
||||||
|
reply_len = -1;
|
||||||
|
} else if (os_strncmp(buf, "SET_CRED ", 9) == 0) {
|
||||||
|
if (wpa_supplicant_ctrl_iface_set_cred(wpa_s, buf + 9))
|
||||||
|
reply_len = -1;
|
||||||
#ifndef CONFIG_NO_CONFIG_WRITE
|
#ifndef CONFIG_NO_CONFIG_WRITE
|
||||||
} else if (os_strcmp(buf, "SAVE_CONFIG") == 0) {
|
} else if (os_strcmp(buf, "SAVE_CONFIG") == 0) {
|
||||||
if (wpa_supplicant_ctrl_iface_save_config(wpa_s))
|
if (wpa_supplicant_ctrl_iface_save_config(wpa_s))
|
||||||
|
|
|
@ -1602,6 +1602,61 @@ static int wpa_cli_cmd_get_network(struct wpa_ctrl *ctrl, int argc,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int wpa_cli_cmd_list_creds(struct wpa_ctrl *ctrl, int argc,
|
||||||
|
char *argv[])
|
||||||
|
{
|
||||||
|
return wpa_ctrl_command(ctrl, "LIST_CREDS");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int wpa_cli_cmd_add_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
|
||||||
|
{
|
||||||
|
return wpa_ctrl_command(ctrl, "ADD_CRED");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int wpa_cli_cmd_remove_cred(struct wpa_ctrl *ctrl, int argc,
|
||||||
|
char *argv[])
|
||||||
|
{
|
||||||
|
char cmd[32];
|
||||||
|
int res;
|
||||||
|
|
||||||
|
if (argc < 1) {
|
||||||
|
printf("Invalid REMOVE_CRED command: needs one argument "
|
||||||
|
"(cred id)\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = os_snprintf(cmd, sizeof(cmd), "REMOVE_CRED %s", argv[0]);
|
||||||
|
if (res < 0 || (size_t) res >= sizeof(cmd))
|
||||||
|
return -1;
|
||||||
|
cmd[sizeof(cmd) - 1] = '\0';
|
||||||
|
|
||||||
|
return wpa_ctrl_command(ctrl, cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int wpa_cli_cmd_set_cred(struct wpa_ctrl *ctrl, int argc, char *argv[])
|
||||||
|
{
|
||||||
|
char cmd[256];
|
||||||
|
int res;
|
||||||
|
|
||||||
|
if (argc != 3) {
|
||||||
|
printf("Invalid SET_CRED command: needs three arguments\n"
|
||||||
|
"(cred id, variable name, and value)\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = os_snprintf(cmd, sizeof(cmd), "SET_CRED %s %s %s",
|
||||||
|
argv[0], argv[1], argv[2]);
|
||||||
|
if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
|
||||||
|
printf("Too long SET_CRED command.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return wpa_ctrl_command(ctrl, cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
|
static int wpa_cli_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
|
||||||
char *argv[])
|
char *argv[])
|
||||||
{
|
{
|
||||||
|
@ -2784,6 +2839,18 @@ static struct wpa_cli_cmd wpa_cli_commands[] = {
|
||||||
{ "get_network", wpa_cli_cmd_get_network,
|
{ "get_network", wpa_cli_cmd_get_network,
|
||||||
cli_cmd_flag_none,
|
cli_cmd_flag_none,
|
||||||
"<network id> <variable> = get network variables" },
|
"<network id> <variable> = get network variables" },
|
||||||
|
{ "list_creds", wpa_cli_cmd_list_creds,
|
||||||
|
cli_cmd_flag_none,
|
||||||
|
"= list configured credentials" },
|
||||||
|
{ "add_cred", wpa_cli_cmd_add_cred,
|
||||||
|
cli_cmd_flag_none,
|
||||||
|
"= add a credential" },
|
||||||
|
{ "remove_cred", wpa_cli_cmd_remove_cred,
|
||||||
|
cli_cmd_flag_none,
|
||||||
|
"<cred id> = remove a credential" },
|
||||||
|
{ "set_cred", wpa_cli_cmd_set_cred,
|
||||||
|
cli_cmd_flag_sensitive,
|
||||||
|
"<cred id> <variable> <value> = set credential variables" },
|
||||||
{ "save_config", wpa_cli_cmd_save_config,
|
{ "save_config", wpa_cli_cmd_save_config,
|
||||||
cli_cmd_flag_none,
|
cli_cmd_flag_none,
|
||||||
"= save the current configuration" },
|
"= save the current configuration" },
|
||||||
|
|
Loading…
Add table
Reference in a new issue