Unload identities from a running daemon

This commit is contained in:
Jeremy Lakeman 2013-10-10 14:22:20 +10:30
parent 221fc4a4fc
commit ef7351bddc
5 changed files with 133 additions and 32 deletions

View File

@ -1965,10 +1965,12 @@ int app_keyring_set_did(const struct cli_parsed *parsed, struct cli_context *con
return 0;
}
int app_id_pin(const struct cli_parsed *parsed, struct cli_context *context)
static int handle_pins(const struct cli_parsed *parsed, struct cli_context *context, int revoke)
{
const char *pin;
const char *pin, *sid_hex;
cli_arg(parsed, "entry-pin", &pin, NULL, "");
cli_arg(parsed, "sid", &sid_hex, str_is_subscriber_id, "");
int ret=1;
struct mdp_header header={
.remote.port=MDP_IDENTITY,
@ -1978,14 +1980,29 @@ int app_id_pin(const struct cli_parsed *parsed, struct cli_context *context)
unsigned char payload[1200];
struct mdp_identity_request *request = (struct mdp_identity_request *)payload;
request->action=ACTION_UNLOCK;
request->type=TYPE_PIN;
if (revoke){
request->action=ACTION_LOCK;
}else{
request->action=ACTION_UNLOCK;
}
int len = sizeof(struct mdp_identity_request);
int pin_len = strlen(pin)+1;
if (pin_len+len > sizeof(payload))
return WHY("Supplied pin is too long");
bcopy(pin, &payload[len], pin_len);
len+=pin_len;
if (pin && *pin){
request->type=TYPE_PIN;
int pin_len = strlen(pin)+1;
if (pin_len+len > sizeof(payload))
return WHY("Supplied pin is too long");
bcopy(pin, &payload[len], pin_len);
len+=pin_len;
}else if(sid_hex && *sid_hex){
request->type=TYPE_SID;
sid_t sid;
if (str_to_sid_t(&sid, sid_hex) == -1)
return WHY("str_to_sid_t() failed");
bcopy(sid.binary, &payload[len], sizeof(sid));
len+=sizeof(sid);
}
if (!mdp_send(mdp_sock, &header, payload, len)){
WHY_perror("mdp_send");
@ -2015,10 +2032,8 @@ int app_id_pin(const struct cli_parsed *parsed, struct cli_context *context)
}
if (rev_header.flags & MDP_FLAG_OK)
ret=0;
if (rev_header.flags & MDP_FLAG_ERROR){
payload[len]=0;
WHYF("%s",payload);
}
if (rev_header.flags & MDP_FLAG_ERROR)
WHY("Operation failed, check the log for more information");
break;
}
end:
@ -2026,6 +2041,16 @@ end:
return ret;
}
int app_revoke_pin(const struct cli_parsed *parsed, struct cli_context *context)
{
return handle_pins(parsed, context, 1);
}
int app_id_pin(const struct cli_parsed *parsed, struct cli_context *context)
{
return handle_pins(parsed, context, 0);
}
int app_id_self(const struct cli_parsed *parsed, struct cli_context *context)
{
int mdp_sockfd;
@ -2583,6 +2608,10 @@ struct cli_schema command_line_options[]={
"Return identity(s) as URIs of own node, or of known routable peers, or all known peers"},
{app_id_pin, {"id", "enter", "pin", "<entry-pin>", NULL}, 0,
"Unlock any pin protected identities and enable routing packets to them"},
{app_revoke_pin, {"id", "revoke", "pin", "<entry-pin>", NULL}, 0,
"Unload any identities protected by this pin and drop all routes to them"},
{app_revoke_pin, {"id", "revoke", "sid", "<sid>", NULL}, 0,
"Unload a specific identity and drop all routes to it"},
{app_route_print, {"route","print",NULL}, 0,
"Print the routing table"},
{app_network_scan, {"scan","[<address>]",NULL}, 0,

View File

@ -29,6 +29,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "overlay_address.h"
static void keyring_free_keypair(keypair *kp);
static void keyring_free_context(keyring_context *c);
static void keyring_free_identity(keyring_identity *id);
static int keyring_identity_mac(const keyring_identity *id, unsigned char *pkrsalt, unsigned char *mac);
static int _keyring_open(keyring_file *k, const char *path, const char *mode)
@ -228,7 +230,25 @@ static void wipestr(char *str)
*str++ = ' ';
}
void keyring_free_context(keyring_context *c)
void keyring_release_identity(keyring_file *k, int cn, int id){
if (config.debug.keyring)
DEBUGF("Releasing k=%p, cn=%d, id=%d", k, cn, id);
keyring_context *c=k->contexts[cn];
c->identity_count--;
keyring_free_identity(c->identities[id]);
if (id!=c->identity_count)
c->identities[id] = c->identities[c->identity_count];
c->identities[c->identity_count]=NULL;
if (c->identity_count==0){
keyring_free_context(c);
k->context_count --;
if (cn!=k->context_count)
k->contexts[cn] = k->contexts[k->context_count];
k->contexts[k->context_count]=NULL;
}
}
static void keyring_free_context(keyring_context *c)
{
int i;
if (!c) return;
@ -247,11 +267,12 @@ void keyring_free_context(keyring_context *c)
/* Wipe out any loaded identities */
for(i=0;i<KEYRING_MAX_IDENTITIES;i++)
if (c->identities[i]) keyring_free_identity(c->identities[i]);
if (c->identities[i])
keyring_free_identity(c->identities[i]);
/* Make sure any private data is wiped out */
bzero(c,sizeof(keyring_context));
free(c);
return;
}
@ -273,6 +294,7 @@ void keyring_free_identity(keyring_identity *id)
id->subscriber->reachable = REACHABLE_NONE;
}
bzero(id,sizeof(keyring_identity));
free(id);
return;
}
@ -305,7 +327,6 @@ int keyring_enter_keyringpin(keyring_file *k, const char *pin)
|| ((c->KeyRingSalt = emalloc(c->KeyRingSaltLen)) == NULL)
) {
keyring_free_context(c);
free(c);
return -1;
}
bcopy(k->contexts[0]->KeyRingSalt, c->KeyRingSalt, c->KeyRingSaltLen);
@ -747,6 +768,7 @@ static void keyring_free_keypair(keypair *kp)
free(kp->public_key);
}
bzero(kp, sizeof(keypair));
free(kp);
}
static keypair *keyring_alloc_keypair(unsigned ktype, size_t len)
@ -1104,10 +1126,8 @@ static int keyring_decrypt_pkr(keyring_file *k, unsigned cn, const char *pin, in
/* Clean up any potentially sensitive data before exiting */
bzero(slot,KEYRING_PAGE_SIZE);
bzero(hash,crypto_hash_sha512_BYTES);
if (id) {
if (id)
keyring_free_identity(id);
id = NULL;
}
return 1;
}

View File

@ -959,26 +959,65 @@ static int mdp_reply2(const struct mdp_client *client, const struct mdp_header *
return sendmsg(mdp_sock2.poll.fd, &hdr, 0);
}
#define mdp_reply_error(A,B,C) mdp_reply2(A,B,MDP_FLAG_ERROR,(const unsigned char *)C,strlen(C))
#define mdp_reply_error(A,B) mdp_reply2(A,B,MDP_FLAG_ERROR,NULL,0)
#define mdp_reply_ok(A,B) mdp_reply2(A,B,MDP_FLAG_OK,NULL,0)
static int mdp_process_identity_request(struct mdp_client *client, struct mdp_header *header,
const unsigned char *payload, int payload_len)
{
if (payload_len<sizeof(struct mdp_identity_request)){
mdp_reply_error(client, header, "Request too short");
return -1;
mdp_reply_error(client, header);
return WHY("Request too small");
}
struct mdp_identity_request *request = (struct mdp_identity_request *)payload;
payload += sizeof(struct mdp_identity_request);
payload_len -= sizeof(struct mdp_identity_request);
switch(request->action){
case ACTION_LOCK:
switch (request->type){
case TYPE_PIN:
{
const char *pin = (char *)payload;
int ofs=0;
while(ofs < payload_len){
if (!payload[ofs++]){
int cn, in;
for (cn = keyring->context_count -1; cn>=0; --cn) {
keyring_context *cx = keyring->contexts[cn];
for (in = cx->identity_count -1; in>=0; --in) {
keyring_identity *id = cx->identities[in];
if (id->subscriber != my_subscriber
&& strcmp(id->PKRPin, pin) == 0){
keyring_release_identity(keyring, cn, in);
}
}
}
pin=(char *)&payload[ofs++];
}
}
}
break;
case TYPE_SID:
while(payload_len>=SID_SIZE){
int cn=0,in=0,kp=0;
if (keyring_find_sid(keyring, &cn, &in, &kp, payload)
&& keyring->contexts[cn]->identities[in]->subscriber != my_subscriber)
keyring_release_identity(keyring, cn, in);
payload+=SID_SIZE;
payload_len-=SID_SIZE;
}
break;
default:
mdp_reply_error(client, header);
return WHY("Unknown request type");
}
break;
case ACTION_UNLOCK:
{
if (request->type!=TYPE_PIN){
mdp_reply_error(client, header, "Unknown request type");
return -1;
mdp_reply_error(client, header);
return WHY("Unknown request type");
}
int unlock_count=0;
const char *pin = (char *)payload;
@ -992,8 +1031,8 @@ static int mdp_process_identity_request(struct mdp_client *client, struct mdp_he
}
break;
default:
mdp_reply_error(client, header, "Unknown request action");
return -1;
mdp_reply_error(client, header);
return WHY("Unknown request action");
}
mdp_reply_ok(client, header);
return 0;
@ -1031,12 +1070,14 @@ static void mdp_poll2(struct sched_ent *alarm)
mdp_process_identity_request(&client, header, payload, payload_len);
break;
default:
mdp_reply_error(&client, header, "Unknown port number");
mdp_reply_error(&client, header);
WHY("Unknown port number");
break;
}
}else{
// TODO transmit packet
mdp_reply_error(&client, header, "Transmitting packets is not yet supported");
mdp_reply_error(&client, header);
WHY("Transmitting packets is not yet supported");
}
}
}

View File

@ -301,8 +301,7 @@ typedef struct keyring_file {
} keyring_file;
void keyring_free(keyring_file *k);
void keyring_free_context(keyring_context *c);
void keyring_free_identity(keyring_identity *id);
void keyring_release_identity(keyring_file *k, int cn, int id);
#define KEYTYPE_CRYPTOBOX 0x01 // must be lowest
#define KEYTYPE_CRYPTOSIGN 0x02
#define KEYTYPE_RHIZOME 0x03

View File

@ -206,7 +206,7 @@ teardown_KeyringKeyringPinServer() {
report_servald_server
}
doc_KeyringEntryPinServer="Start daemon and unlock identities"
doc_KeyringEntryPinServer="Start daemon, unlock and lock identities"
setup_KeyringEntryPinServer() {
setup
executeOk_servald config set debug.mdprequests on
@ -235,6 +235,18 @@ test_KeyringEntryPinServer() {
assertStdoutGrep --fixed-strings "$ONE"
assertStdoutGrep --fixed-strings "$TWOA"
assertStdoutGrep --fixed-strings "$TWOB"
executeOk_servald id revoke pin 'one'
executeOk_servald id self
assertStdoutLineCount == 3
assertStdoutGrep --fixed-strings "$SIDA"
assertStdoutGrep --fixed-strings "$TWOA"
assertStdoutGrep --fixed-strings "$TWOB"
executeOk_servald id revoke sid "$TWOB"
tfw_cat --stderr
executeOk_servald id self
assertStdoutLineCount == 2
assertStdoutGrep --fixed-strings "$SIDA"
assertStdoutGrep --fixed-strings "$TWOA"
}
teardown_KeyringEntryPinServer() {
kill_all_servald_processes