Skip to content

Commit ceb7a20

Browse files
committed
(WIP) feat: add bash completion for p11* tools
1 parent d5a7844 commit ceb7a20

25 files changed

Lines changed: 776 additions & 2 deletions

Makefile.am

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,32 @@ SUBDIRS = gl lib src
4141
ACLOCAL_AMFLAGS = -I m4
4242

4343

44+
completionsdir = $(datadir)/bash-completion/completions
45+
completions_DATA = \
46+
completion/p11-common \
47+
completion/p11cat \
48+
completion/p11cp \
49+
completion/p11importcert \
50+
completion/p11importdata \
51+
completion/p11importpubk \
52+
completion/p11kcv \
53+
completion/p11keycomp \
54+
completion/p11keygen \
55+
completion/p11ls \
56+
completion/p11mkcert \
57+
completion/p11more \
58+
completion/p11mv \
59+
completion/p11od \
60+
completion/p11req \
61+
completion/p11rewrap \
62+
completion/p11rm \
63+
completion/p11setattr \
64+
completion/p11slotinfo \
65+
completion/p11unwrap \
66+
completion/p11wrap
67+
68+
EXTRA_DIST += $(completions_DATA)
69+
4470
install-exec-hook:
4571
$(INSTALL) \
4672
$(srcdir)/with_beid \

completion/p11-common

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# Common functions for p11* completion scripts -*- shell-script -*-
2+
#
3+
# Description:
4+
# This file provides reusable Bash functions to support autocompletion
5+
# for various `p11*` CLI tools (p11cat, p11cp, p11mv, etc.).
6+
#
7+
# Functions parse the command-line arguments dynamically and provide
8+
# object filtering and completion based on loaded tokens via `p11ls`.
9+
#
10+
# Functions:
11+
# - __p11_parse_args(slot_ref, pin_ref, lib_ref)
12+
# Parses -l (lib), -s (slot), -p (pin) from COMP_WORDS into referenced variables
13+
#
14+
# - __p11_complete_slots(cur)
15+
# Uses parsed lib to call p11slotinfo with -L and generate
16+
# autocompletion candidates for slot numbers used with -s.
17+
#
18+
# - __p11_complete_filters(cur)
19+
# Uses parsed lib/slot/pin to call p11ls and generate autocompletion candidates
20+
# with existing filters.
21+
#
22+
# Environment:
23+
# These variables are used as fallback if -l, -s or -p are not given:
24+
# PKCS11LIB, PKCS11SLOT, PKCS11PASSWORD
25+
#
26+
# Limitations:
27+
#
28+
# Inline environment variable assignments like the following:
29+
# PKCS11LIB=/usr/lib/softhsm/libsofthsm2.so p11ls -s 0 -p 1234
30+
#
31+
# will NOT be detected by Bash completion logic, because these assignments
32+
# are not part of the shell's environment when autocompletion is triggered.
33+
#
34+
# Instead, define them in the environment using `export`:
35+
# export PKCS11LIB=/usr/lib/softhsm/libsofthsm2.so
36+
# export PKCS11SLOT=0
37+
# export PKCS11PASSWORD=1234
38+
# p11ls <TAB>
39+
#
40+
# This ensures that completion functions can access the variables reliably.
41+
#
42+
# Usage:
43+
# Must be sourced by specific completion scripts, e.g.:
44+
# source /usr/share/bash-completion/completions/p11-common
45+
46+
__p11_parse_args() {
47+
local -n _slot=$1 _pin=$2 _lib=$3
48+
_slot=""; _pin=""; _lib=""
49+
50+
for ((i=0; i < ${#COMP_WORDS[@]}; i++)); do
51+
case "${COMP_WORDS[i]}" in
52+
-s) _slot="${COMP_WORDS[i+1]}" ;;
53+
-p) _pin="${COMP_WORDS[i+1]}" ;;
54+
-l) _lib="${COMP_WORDS[i+1]}" ;;
55+
esac
56+
done
57+
58+
# Fallback to env vars if CLI args not provided
59+
[[ -z "$_lib" && -n "$PKCS11LIB" ]] && _lib="$PKCS11LIB"
60+
[[ -z "$_slot" && -n "$PKCS11SLOT" ]] && _slot="$PKCS11SLOT"
61+
[[ -z "$_pin" && -n "$PKCS11PASSWORD" ]] && _pin="$PKCS11PASSWORD"
62+
}
63+
64+
__p11_complete_slots() {
65+
local cur="$1"
66+
local slot pin lib
67+
__p11_parse_args slot pin lib
68+
69+
if [[ -n "$lib" ]]; then
70+
local slots
71+
slots=$(p11slotinfo -l "$lib" -L 2>/dev/null | awk -F: '{print $1}')
72+
COMPREPLY=( $(compgen -W "${slots}" -- "${cur}") )
73+
fi
74+
}
75+
76+
77+
__p11_complete_filters() {
78+
local slot pin lib cur="$1"
79+
__p11_parse_args slot pin lib
80+
81+
if [[ -n "$lib" && -n "$slot" && -n "$pin" ]]; then
82+
local objects
83+
objects=$(p11ls -l "$lib" -s "$slot" -p "$pin" 2>/dev/null | awk '{print $1}')
84+
COMPREPLY=( $(compgen -W "${objects}" -- "${cur}") )
85+
fi
86+
}

completion/p11cat

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# p11cat(1) completion -*- shell-script -*-
2+
#
3+
# Bash autocompletion for `p11cat`.
4+
# Provides dynamic suggestions for PKCS#11 object filters
5+
# based on current lib, slot, and pin arguments.
6+
#
7+
# Depends on:
8+
# - ./p11-common
9+
#
10+
# Usage:
11+
# Autocompletes when user types:
12+
# p11cat -l <lib> -s <slot> -p <pin> <TAB>
13+
14+
source "$(dirname "${BASH_SOURCE[0]}")/p11-common"
15+
16+
_p11cat_opts="-l -m -s -t -p -S -x -h -V"
17+
18+
_p11cat() {
19+
local cur="${COMP_WORDS[COMP_CWORD]}"
20+
local prev="${COMP_WORDS[COMP_CWORD-1]}"
21+
22+
if [[ "$prev" == "-s" ]]; then
23+
__p11_complete_slots "$cur"
24+
return
25+
fi
26+
27+
if [[ "$cur" == -* ]]; then
28+
COMPREPLY=( $(compgen -W "${_p11cat_opts}" -- "$cur") )
29+
return
30+
fi
31+
32+
__p11_complete_filters "$cur"
33+
}
34+
35+
complete -F _p11cat p11cat

completion/p11cp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# p11cp(1) completion -*- shell-script -*-
2+
#
3+
# Bash autocompletion for `p11cp`.
4+
# Provides dynamic suggestions for the SOURCE argument
5+
# based on current lib, slot, and pin arguments.
6+
#
7+
# Depends on:
8+
# - ./p11-common
9+
#
10+
# Usage:
11+
# Autocompletes when user types:
12+
# p11cp -l <lib> -s <slot> -p <pin> <TAB>
13+
14+
source "$(dirname "${BASH_SOURCE[0]}")/p11-common"
15+
16+
_p11cp_opts="-l -m -s -t -p -S -y -v -h -V"
17+
18+
_p11cp() {
19+
local cur="${COMP_WORDS[COMP_CWORD]}"
20+
local prev="${COMP_WORDS[COMP_CWORD-1]}"
21+
22+
if [[ "$prev" == "-s" ]]; then
23+
__p11_complete_slots "$cur"
24+
return
25+
fi
26+
27+
if [[ "$cur" == -* ]]; then
28+
COMPREPLY=( $(compgen -W "${_p11cp_opts}" -- "$cur") )
29+
return
30+
fi
31+
32+
__p11_complete_filters "$cur"
33+
}
34+
35+
complete -F _p11cp p11cp

completion/p11importcert

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# p11importcert(1) completion -*- shell-script -*-
2+
#
3+
# Bash autocompletion for `p11importcert`.
4+
# Provides dynamic suggestions.
5+
6+
_p11importcert_opts="-l -m -s -t -p -f -i -T -S -h -V"
7+
8+
_p11importcert() {
9+
local cur="${COMP_WORDS[COMP_CWORD]}"
10+
local prev="${COMP_WORDS[COMP_CWORD-1]}"
11+
12+
if [[ "$prev" == "-s" ]]; then
13+
__p11_complete_slots "$cur"
14+
return
15+
fi
16+
17+
if [[ "$cur" == -* ]]; then
18+
COMPREPLY=( $(compgen -W "${_p11importcert_opts}" -- "$cur") )
19+
return
20+
fi
21+
}
22+
23+
complete -F _p11importcert p11importcert

completion/p11importdata

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# p11importdata(1) completion -*- shell-script -*-
2+
#
3+
# Bash autocompletion for `p11importdata`.
4+
# Provides dynamic suggestions.
5+
6+
_p11importdata_opts="-l -m -s -t -p -f -i -h -V"
7+
8+
_p11importdata() {
9+
local cur="${COMP_WORDS[COMP_CWORD]}"
10+
local prev="${COMP_WORDS[COMP_CWORD-1]}"
11+
12+
if [[ "$prev" == "-s" ]]; then
13+
__p11_complete_slots "$cur"
14+
return
15+
fi
16+
17+
if [[ "$cur" == -* ]]; then
18+
COMPREPLY=( $(compgen -W "${_p11importdata_opts}" -- "$cur") )
19+
return
20+
fi
21+
}
22+
23+
complete -F _p11importdata p11importdata

completion/p11importpubk

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# p11importpubk(1) completion -*- shell-script -*-
2+
#
3+
# Bash autocompletion for `p11importpubk`.
4+
# Provides dynamic suggestions.
5+
6+
_p11importpubk_opts="-l -m -s -t -p -f -i -T -S -h -V"
7+
8+
_p11importpubk() {
9+
local cur="${COMP_WORDS[COMP_CWORD]}"
10+
local prev="${COMP_WORDS[COMP_CWORD-1]}"
11+
12+
if [[ "$prev" == "-s" ]]; then
13+
__p11_complete_slots "$cur"
14+
return
15+
fi
16+
17+
if [[ "$cur" == -* ]]; then
18+
COMPREPLY=( $(compgen -W "${_p11importpubk_opts}" -- "$cur") )
19+
return
20+
fi
21+
}
22+
23+
complete -F _p11importpubk p11importpubk

completion/p11kcv

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# p11kcv(1) completion -*- shell-script -*-
2+
#
3+
# Bash autocompletion for `p11kcv`.
4+
# Provides dynamic suggestions for PKCS#11 object filters
5+
# based on current lib, slot, and pin arguments.
6+
#
7+
# Depends on:
8+
# - ./p11-common
9+
#
10+
# Usage:
11+
# Autocompletes when user types:
12+
# p11kcv -l <lib> -s <slot> -p <pin> <TAB>
13+
14+
source "$(dirname "${BASH_SOURCE[0]}")/p11-common"
15+
16+
_p11kcv_opts="-l -m -s -t -p -S -b -n -f -h -V"
17+
18+
_p11kcv() {
19+
local cur="${COMP_WORDS[COMP_CWORD]}"
20+
local prev="${COMP_WORDS[COMP_CWORD-1]}"
21+
22+
if [[ "$prev" == "-s" ]]; then
23+
__p11_complete_slots "$cur"
24+
return
25+
fi
26+
27+
if [[ "$cur" == -* ]]; then
28+
COMPREPLY=( $(compgen -W "${_p11kcv_opts}" -- "$cur") )
29+
return
30+
fi
31+
32+
__p11_complete_filters "$cur"
33+
}
34+
35+
complete -F _p11kcv p11kcv

completion/p11keycomp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# p11keycomp(1) completion -*- shell-script -*-
2+
#
3+
# Bash autocompletion for `p11keycomp`.
4+
# Provides dynamic suggestions.
5+
6+
_p11keycomp_opts="-l -m -s -t -p -i -c -w -S -h -V"
7+
8+
_p11keycomp() {
9+
local cur="${COMP_WORDS[COMP_CWORD]}"
10+
local prev="${COMP_WORDS[COMP_CWORD-1]}"
11+
12+
if [[ "$prev" == "-s" ]]; then
13+
__p11_complete_slots "$cur"
14+
return
15+
fi
16+
17+
if [[ "$cur" == -* ]]; then
18+
COMPREPLY=( $(compgen -W "${_p11keycomp_opts}" -- "$cur") )
19+
return
20+
fi
21+
}
22+
23+
complete -F _p11keycomp p11keycomp

completion/p11keygen

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# p11keygen(1) completion -*- shell-script -*-
2+
#
3+
# Bash autocompletion for `p11keygen`.
4+
# Provides dynamic suggestions.
5+
6+
_p11keygen_opts="-l -m -s -t -p -S -i -k -b -e -q -d -W -J -r -h -V"
7+
8+
_p11keygen() {
9+
local cur="${COMP_WORDS[COMP_CWORD]}"
10+
local prev="${COMP_WORDS[COMP_CWORD-1]}"
11+
12+
if [[ "$prev" == "-s" ]]; then
13+
__p11_complete_slots "$cur"
14+
return
15+
fi
16+
17+
if [[ "$cur" == -* ]]; then
18+
COMPREPLY=( $(compgen -W "${_p11keygen_opts}" -- "$cur") )
19+
return
20+
fi
21+
}
22+
23+
complete -F _p11keygen p11keygen

0 commit comments

Comments
 (0)