diff --git a/keyring.c b/keyring.c index 0a369c6e..4b272104 100644 --- a/keyring.c +++ b/keyring.c @@ -290,7 +290,7 @@ void keyring_free_identity(keyring_identity *id) int keyring_enter_keyringpin(keyring_file *k, const char *pin) { if (config.debug.keyring) - DEBUGF("k=%p", k); + DEBUGF("k=%p pin=%s", k, alloca_str_toprint(pin)); if (!k) return WHY("k is null"); if (k->context_count >= KEYRING_MAX_CONTEXTS) @@ -325,9 +325,10 @@ int keyring_enter_keyringpin(keyring_file *k, const char *pin) level function, and all we need to know here is that we shouldn't decrypt the first 96 bytes of the block. */ -int keyring_munge_block(unsigned char *block,int len /* includes the first 96 bytes */, - unsigned char *KeyRingSalt,int KeyRingSaltLen, - const char *KeyRingPin, const char *PKRPin) +static int keyring_munge_block( + unsigned char *block, int len /* includes the first 96 bytes */, + unsigned char *KeyRingSalt, int KeyRingSaltLen, + const char *KeyRingPin, const char *PKRPin) { if (config.debug.keyring) DEBUGF("KeyRingPin=%s PKRPin=%s", alloca_str_toprint(KeyRingPin), alloca_str_toprint(PKRPin)); @@ -1055,8 +1056,12 @@ static int keyring_identity_mac(const keyring_identity *id, unsigned char *pkrsa * munged, we then need to verify that the slot is valid, and if so unpack the details of the * identity. */ -int keyring_decrypt_pkr(keyring_file *k, keyring_context *c, const char *pin, int slot_number) +static int keyring_decrypt_pkr(keyring_file *k, unsigned cn, const char *pin, int slot_number) { + if (config.debug.keyring) + DEBUGF("k=%p, cn=%u pin=%s slot_number=%d", k, cn, alloca_str_toprint(pin), slot_number); + assert(cn < k->context_count); + keyring_context *cx = k->contexts[cn]; unsigned char slot[KEYRING_PAGE_SIZE]; keyring_identity *id=NULL; @@ -1066,7 +1071,7 @@ int keyring_decrypt_pkr(keyring_file *k, keyring_context *c, const char *pin, in if (fread(slot, KEYRING_PAGE_SIZE, 1, k->file) != 1) return WHY_perror("fread"); /* 2. Decrypt data from slot. */ - if (keyring_munge_block(slot, KEYRING_PAGE_SIZE, c->KeyRingSalt, c->KeyRingSaltLen, c->KeyRingPin, pin)) { + if (keyring_munge_block(slot, KEYRING_PAGE_SIZE, cx->KeyRingSalt, cx->KeyRingSaltLen, cx->KeyRingPin, pin)) { WHYF("keyring_munge_block() failed, slot=%u", slot_number); goto kdp_safeexit; } @@ -1097,7 +1102,7 @@ int keyring_decrypt_pkr(keyring_file *k, keyring_context *c, const char *pin, in } } /* All fine, so add the id into the context and return. */ - c->identities[c->identity_count++]=id; + cx->identities[cx->identity_count++] = id; return 0; kdp_safeexit: @@ -1125,9 +1130,9 @@ int keyring_enter_pin(keyring_file *k, const char *pin) // Check if PIN is already entered. { - unsigned c; - for (c = 0; c < k->context_count; ++c) { - keyring_context *cx = k->contexts[c]; + unsigned cn; + for (cn = 0; cn < k->context_count; ++cn) { + keyring_context *cx = k->contexts[cn]; unsigned i; for (i = 0; i < cx->identity_count; ++i) { keyring_identity *id = cx->identities[i]; @@ -1159,9 +1164,9 @@ int keyring_enter_pin(keyring_file *k, const char *pin) if (b->bitmap[byte]&(1<context_count;c++) - if (keyring_decrypt_pkr(k,k->contexts[c],pin?pin:"",slot) == 0) + int cn; + for (cn = 0; cn < k->context_count; ++cn) + if (keyring_decrypt_pkr(k, cn, pin, slot) == 0) ++identitiesFound; } } @@ -1730,8 +1735,10 @@ int keyring_seed(keyring_file *k) if (!k) return WHY("keyring is null"); /* nothing to do if there is already an identity */ - if (k->contexts[0]->identity_count) - return 0; + unsigned cn; + for (cn = 0; cn < k->context_count; ++cn) + if (k->contexts[cn]->identity_count) + return 0; int i; char did[65]; /* Securely generate random telephone number */ diff --git a/overlay.c b/overlay.c index 436a5cda..6c70d943 100644 --- a/overlay.c +++ b/overlay.c @@ -91,7 +91,6 @@ int overlayServerMode(const struct cli_parsed *parsed) keyring = keyring_open_instance_cli(parsed); if (!keyring) RETURN(WHY("Could not open serval keyring file.")); - keyring_enter_pin(keyring, ""); /* put initial identity in if we don't have any visible */ keyring_seed(keyring); diff --git a/testdefs.sh b/testdefs.sh index 3b0608d6..8accb63b 100644 --- a/testdefs.sh +++ b/testdefs.sh @@ -542,7 +542,11 @@ assert_all_servald_servers_no_errors() { } # Utility function -# - create an identity in the current instance {I} +# +# create_single_identity [--option]... [ DID [ Name ]] +# +# - create an identity in the current instance {I} by invoking the command: +# servald keyring add [--option]... # - assign a phone number (DID) and name to the new identity, use defaults # if not specified by arg1 and arg2 # - assert the new identity is the only one in this instance @@ -550,12 +554,19 @@ assert_all_servald_servers_no_errors() { # - set the DID{I} variable, eg DIDA, to the phone number of the new identity # - set the NAME{I} variable, eg NAMEA, to the name of the new identity create_single_identity() { + local servald_options=() + while [ $# -gt 0 ]; do + case "$1" in + --*) servald_options+=("$1"); shift;; + *) break;; + esac + done local sidvar=SID${instance_name}1 local didvar=DID${instance_name}1 local namevar=NAME${instance_name}1 eval "$didvar=\"\${1-\$((5550000 + \$instance_number))}\"" eval "$namevar=\"\${2-Agent \$instance_name Smith}\"" - create_identities 1 + create_identities "${servald_options[@]}" 1 eval "SID$instance_name=\"\${!sidvar}\"" eval "DID$instance_name=\"\${!didvar}\"" eval "NAME$instance_name=\"\${!namevar}\"" @@ -568,7 +579,12 @@ create_single_identity() { } # Utility function: -# - create N identities in the current instance {I} +# +# create_identities [--option]... N +# +# - create N identities in the current instance {I} using N consecutive +# invocations of: servald keyring add [--option]... +# - pass [args...] to the keyring add # - if variables DID{I}{1..N} and/or NAME{I}{1..N} are already set, then use # them to set the DIDs and names of each identity # - assert that all SIDs are unique @@ -577,14 +593,22 @@ create_single_identity() { # - set variables DID{I}{1..N} to DIDs of identities, eg, DIDA1, DIDA2... # - set variables NAME{I}{1..N} to names of identities, eg, NAMEA1, NAMEA2... create_identities() { + local servald_options=() + while [ $# -gt 0 ]; do + case "$1" in + --*) servald_options+=("$1"); shift;; + *) break;; + esac + done local N="$1" case "$N" in +([0-9]));; *) error "invalid arg1: $N";; esac + shift local i j for ((i = 1; i <= N; ++i)); do - executeOk_servald keyring add + executeOk_servald keyring add "${servald_options[@]}" assert [ -e "$SERVALINSTANCE_PATH/serval.keyring" ] local sidvar=SID$instance_name$i local didvar=DID$instance_name$i @@ -595,7 +619,7 @@ create_identities() { # them, otherwise extract the DID and NAME automatically generated by # servald. if [ -n "${!didvar}" -o -n "${!namevar}" ]; then - executeOk_servald keyring set did "${!sidvar}" "${!didvar}" "${!namevar}" + executeOk_servald keyring set did "${servald_options[@]}" "${!sidvar}" "${!didvar}" "${!namevar}" eval "$didvar=\${!didvar}" eval "$namevar=\${!namevar}" tfw_log "$didvar=$(shellarg "${!didvar}")" @@ -610,7 +634,7 @@ create_identities() { [ $i -ne $j ] && eval assert [ "\$SID$instance_name$i" != "\$SID$instance_name$j" ] done done - executeOk_servald keyring list + executeOk_servald keyring list "${servald_options[@]}" assertStdoutLineCount '==' $N for ((i = 1; i <= N; ++i)); do local sidvar=SID$instance_name$i diff --git a/tests/keyring b/tests/keyring index 5b4c27bf..63472d35 100755 --- a/tests/keyring +++ b/tests/keyring @@ -146,6 +146,26 @@ teardown_KeyringAutoCreate() { report_servald_server } +doc_KeyringPinServer="Start a server with a keyring PIN" +setup_KeyringPinServer() { + setup + create_single_identity --keyring-pin=yellow +} +test_KeyringPinServer() { + start_servald_server --keyring-pin=yellow + executeOk_servald id self + assertStdoutLineCount == 1 + assertStdoutGrep --fixed-strings "$SIDA" +} +finally_KeyringPinServer() { + stop_servald_server +} +teardown_KeyringPinServer() { + kill_all_servald_processes + assert_no_servald_processes + report_servald_server +} + doc_Load="Load keyring entries from a keyring dump" setup_Load() { setup_servald