Message ID | 20220822074318.291949-2-raphael.melotte@mind.be |
---|---|
State | New |
Headers | show |
Series | iw: add support for retrieving keys | expand |
On Mon, 2022-08-22 at 09:43 +0200, Raphaël Mélotte wrote: > For debugging purposes, it can be useful to be able to retrieve keys. > > Add a "iw get key" command, to be able to retrieve keys when the key > index is known. > > Example retrieving a pairwise key: > iw dev wlan0 get key 0 02:02:03:04:05:06 > > Example retrieving a group key: > iw dev wlan0 get key 1 The examples don't seem to match the docs: > +COMMAND(get, key, "", > + NL80211_CMD_GET_KEY, 0, CIB_NETDEV, handle_get_key, > + "<key index> <MAC address> <pairwise>\n"); and maybe you should switch pairwise/mac addr since it's not required for pairwise == false I guess? or maybe let you specify the key type instead, so you can retrieve other kinds of keys? > + if (argc) { > + if (mac_addr_a2n(mac, argv[0]) == 0) { > + NLA_PUT(msg, NL80211_ATTR_MAC, 6, mac); > + argv++; > + argc--; > + nla_put_u32(msg, NL80211_ATTR_KEY_TYPE, > NL80211_KEYTYPE_PAIRWISE); > + } and this seems like it could have some error return in the else or something? Otherwise seems fine to me, any particular reason you sent it as RFC? johannes
On 12/1/22 14:37, Johannes Berg wrote: > The examples don't seem to match the docs: Indeed.. I'll fix it. > and maybe you should switch pairwise/mac addr since it's not required > for pairwise == false I guess? or maybe let you specify the key type > instead, so you can retrieve other kinds of keys? I was actually thinking about removing the pairwise flag entirely. Since the kernel currently only allows to retrieve pairwise or group keys (AFAICT), I was thinking it could be easier to use the presence of the MAC address to differentiate between the key types. > > and this seems like it could have some error return in the else or > something? Indeed, I'll add it. > > Otherwise seems fine to me, any particular reason you sent it as RFC? I thought there might have been a specific reason why it was not there yet, and I also wasn't sure about 'NL80211_KEY_*' vs 'NL80211_ATTR_KEY_*'. I'll send a v2 addressing the comments above. Thanks for the review! Raphaël
diff --git a/Makefile b/Makefile index 33aaf6a..aa4ce7e 100644 --- a/Makefile +++ b/Makefile @@ -23,7 +23,7 @@ OBJS = iw.o genl.o event.o info.o phy.o \ mesh.o mpath.o mpp.o scan.o reg.o version.o \ reason.o status.o connect.o link.o offch.o ps.o cqm.o \ bitrate.o wowlan.o coalesce.o roc.o p2p.o vendor.o mgmt.o \ - ap.o sha256.o nan.o bloom.o \ + ap.o sha256.o nan.o bloom.o keys.o \ measurements.o ftm.o OBJS += sections.o diff --git a/keys.c b/keys.c new file mode 100644 index 0000000..3cb2950 --- /dev/null +++ b/keys.c @@ -0,0 +1,77 @@ +#include <errno.h> +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <netlink/msg.h> +#include <netlink/attr.h> +#include "nl80211.h" +#include "iw.h" + +static int print_keys(struct nl_msg *msg, void *arg) +{ + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + struct nlattr *tb[NL80211_ATTR_MAX + 1]; + + nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), + genlmsg_attrlen(gnlh, 0), NULL); + + if (!tb[NL80211_ATTR_KEY_IDX]) { + fprintf(stderr, "KEY_IDX missing!\n"); + return NL_SKIP; + } + + if (!tb[NL80211_ATTR_KEY_DATA]) { + fprintf(stderr, "ATTR_KEY_DATA missing!\n"); + return NL_SKIP; + } + + iw_hexdump("Key", nla_data(tb[NL80211_ATTR_KEY_DATA]), + nla_len(tb[NL80211_ATTR_KEY_DATA])); + + if (!tb[NL80211_ATTR_KEY_SEQ]) { + fprintf(stderr, "ATTR_KEY_SEQ missing!\n"); + return NL_SKIP; + } + + iw_hexdump("Key seq", nla_data(tb[NL80211_ATTR_KEY_SEQ]), + nla_len(tb[NL80211_ATTR_KEY_SEQ])); + + return NL_OK; +} + +static int handle_get_key(struct nl80211_state *state, + struct nl_msg *msg, int argc, char **argv, + enum id_input id) +{ + char *end; + unsigned char mac[6]; + + /* key index */ + if (argc) { + nla_put_u8(msg, NL80211_ATTR_KEY_IDX, strtoul(argv[0], &end, 10)); + argv++; + argc--; + } + + /* mac */ + if (argc) { + if (mac_addr_a2n(mac, argv[0]) == 0) { + NLA_PUT(msg, NL80211_ATTR_MAC, 6, mac); + argv++; + argc--; + nla_put_u32(msg, NL80211_ATTR_KEY_TYPE, NL80211_KEYTYPE_PAIRWISE); + } + } else { + nla_put_u32(msg, NL80211_ATTR_KEY_TYPE, NL80211_KEYTYPE_GROUP); + } + + register_handler(print_keys, NULL); + return 0; + + nla_put_failure: + return -ENOSPC; +} + +COMMAND(get, key, "", + NL80211_CMD_GET_KEY, 0, CIB_NETDEV, handle_get_key, + "<key index> <MAC address> <pairwise>\n");
For debugging purposes, it can be useful to be able to retrieve keys. Add a "iw get key" command, to be able to retrieve keys when the key index is known. Example retrieving a pairwise key: iw dev wlan0 get key 0 02:02:03:04:05:06 Example retrieving a group key: iw dev wlan0 get key 1 Note that only the outer ATTR_KEY_DATA (and seq) is reported, the nested KEY_DATA (and seq) within ATTR_KEY is not. Signed-off-by: Raphaël Mélotte <raphael.melotte@mind.be> --- Makefile | 2 +- keys.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 keys.c