mirror of
https://github.com/servalproject/serval-dna.git
synced 2024-12-20 13:43:12 +00:00
DNA replies now include name. "set did" now accepts name.
Keyring now stores name. "node info resolvedid" now returns name.
This commit is contained in:
parent
4234cb3ed5
commit
14e4af6392
@ -1109,12 +1109,14 @@ int app_keyring_add(int argc, const char *const *argv, struct command_line_optio
|
|||||||
|
|
||||||
int app_keyring_set_did(int argc, const char *const *argv, struct command_line_option *o)
|
int app_keyring_set_did(int argc, const char *const *argv, struct command_line_option *o)
|
||||||
{
|
{
|
||||||
const char *sid, *did, *pin;
|
const char *sid, *did, *pin, *name;
|
||||||
cli_arg(argc, argv, o, "sid", &sid, NULL, "");
|
cli_arg(argc, argv, o, "sid", &sid, NULL, "");
|
||||||
cli_arg(argc, argv, o, "did", &did, NULL, "");
|
cli_arg(argc, argv, o, "did", &did, NULL, "");
|
||||||
|
cli_arg(argc, argv, o, "name", &name, NULL, "");
|
||||||
cli_arg(argc, argv, o, "pin", &pin, NULL, "");
|
cli_arg(argc, argv, o, "pin", &pin, NULL, "");
|
||||||
|
|
||||||
if (strlen(did)>31) return WHY("DID too long (31 digits max)");
|
if (strlen(did)>31) return WHY("DID too long (31 digits max)");
|
||||||
|
if (strlen(name)>63) return WHY("Name too long (31 char max)");
|
||||||
|
|
||||||
keyring=keyring_open_with_pins((char *)pin);
|
keyring=keyring_open_with_pins((char *)pin);
|
||||||
if (!keyring) return WHY("Could not open keyring file");
|
if (!keyring) return WHY("Could not open keyring file");
|
||||||
@ -1125,7 +1127,8 @@ int app_keyring_set_did(int argc, const char *const *argv, struct command_line_o
|
|||||||
int cn=0,in=0,kp=0;
|
int cn=0,in=0,kp=0;
|
||||||
int r=keyring_find_sid(keyring,&cn,&in,&kp,packedSid);
|
int r=keyring_find_sid(keyring,&cn,&in,&kp,packedSid);
|
||||||
if (!r) return WHY("No matching SID");
|
if (!r) return WHY("No matching SID");
|
||||||
if (keyring_set_did(keyring->contexts[cn]->identities[in],(char *)did))
|
if (keyring_set_did(keyring->contexts[cn]->identities[in],
|
||||||
|
(char *)did,(char *)name))
|
||||||
return WHY("Could not set DID");
|
return WHY("Could not set DID");
|
||||||
if (keyring_commit(keyring))
|
if (keyring_commit(keyring))
|
||||||
return WHY("Could not write updated keyring record");
|
return WHY("Could not write updated keyring record");
|
||||||
@ -1239,9 +1242,10 @@ int app_node_info(int argc, const char *const *argv, struct command_line_option
|
|||||||
if (!overlay_mdp_send(&m2,MDP_AWAITREPLY,125))
|
if (!overlay_mdp_send(&m2,MDP_AWAITREPLY,125))
|
||||||
{
|
{
|
||||||
int bytes=m2.in.payload_length;
|
int bytes=m2.in.payload_length;
|
||||||
if ((bytes+1)<sizeof(mdp.nodeinfo.did))
|
if ((bytes+1)<sizeof(mdp.nodeinfo.did)+sizeof(mdp.nodeinfo.name))
|
||||||
{
|
{
|
||||||
bcopy(&m2.in.payload[0],&mdp.nodeinfo.did[0],bytes);
|
bcopy(&m2.in.payload[0],&mdp.nodeinfo.did[0],32);
|
||||||
|
bcopy(&m2.in.payload[32],&mdp.nodeinfo.name[0],64);
|
||||||
mdp.nodeinfo.did[bytes]=0;
|
mdp.nodeinfo.did[bytes]=0;
|
||||||
mdp.nodeinfo.resolve_did=1;
|
mdp.nodeinfo.resolve_did=1;
|
||||||
}
|
}
|
||||||
@ -1266,7 +1270,8 @@ int app_node_info(int argc, const char *const *argv, struct command_line_option
|
|||||||
cli_printf("%s",mdp.nodeinfo.neighbourP?"direct":"indirect");
|
cli_printf("%s",mdp.nodeinfo.neighbourP?"direct":"indirect");
|
||||||
cli_delim(":");
|
cli_delim(":");
|
||||||
cli_printf("%d",mdp.nodeinfo.score); cli_delim(":");
|
cli_printf("%d",mdp.nodeinfo.score); cli_delim(":");
|
||||||
cli_printf("%d",mdp.nodeinfo.interface_number);
|
cli_printf("%d",mdp.nodeinfo.interface_number); cli_delim(":");
|
||||||
|
cli_printf("%s",mdp.nodeinfo.resolve_did?mdp.nodeinfo.name:"name-not-resolved");
|
||||||
cli_delim("\n");
|
cli_delim("\n");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -1328,7 +1333,7 @@ command_line_option command_line_options[]={
|
|||||||
"List identites in specified key ring that can be accessed using the specified PINs"},
|
"List identites in specified key ring that can be accessed using the specified PINs"},
|
||||||
{app_keyring_add,{"keyring","add","[<pin>]",NULL},CLIFLAG_STANDALONE,
|
{app_keyring_add,{"keyring","add","[<pin>]",NULL},CLIFLAG_STANDALONE,
|
||||||
"Create a new identity in the keyring protected by the provided PIN"},
|
"Create a new identity in the keyring protected by the provided PIN"},
|
||||||
{app_keyring_set_did,{"set","did","<sid>","<did>","[<pin>]",NULL},CLIFLAG_STANDALONE,
|
{app_keyring_set_did,{"set","did","<sid>","<did>","<name>","[<pin>]",NULL},CLIFLAG_STANDALONE,
|
||||||
"Set the DID for the specified SID. Optionally supply PIN to unlock the SID record in the keyring."},
|
"Set the DID for the specified SID. Optionally supply PIN to unlock the SID record in the keyring."},
|
||||||
{app_vomp_status,{"vomp","status",NULL},0,
|
{app_vomp_status,{"vomp","status",NULL},0,
|
||||||
"Display status of any VoMP calls"},
|
"Display status of any VoMP calls"},
|
||||||
|
59
keyring.c
59
keyring.c
@ -425,9 +425,26 @@ int keyring_pack_identity(keyring_context *c,keyring_identity *i,
|
|||||||
switch(i->keypairs[kp]->type) {
|
switch(i->keypairs[kp]->type) {
|
||||||
case KEYTYPE_RHIZOME:
|
case KEYTYPE_RHIZOME:
|
||||||
case KEYTYPE_DID:
|
case KEYTYPE_DID:
|
||||||
/* Both of these are 32 bytes and only one value,
|
/* 32 chars for unpacked DID/rhizome secret,
|
||||||
so the CRYPTOBOX case below works */
|
64 chars for name (for DIDs only) */
|
||||||
/* fall through */
|
if ((ofs
|
||||||
|
+i->keypairs[kp]->private_key_len
|
||||||
|
+i->keypairs[kp]->public_key_len
|
||||||
|
)>=KEYRING_PAGE_SIZE)
|
||||||
|
{
|
||||||
|
WHY("too many or too long key pairs");
|
||||||
|
ofs=0;
|
||||||
|
goto kpi_safeexit;
|
||||||
|
}
|
||||||
|
bcopy(i->keypairs[kp]->private_key,&packed[ofs],
|
||||||
|
i->keypairs[kp]->private_key_len);
|
||||||
|
ofs+=i->keypairs[kp]->private_key_len;
|
||||||
|
if (i->keypairs[kp]->type==KEYTYPE_DID) {
|
||||||
|
bcopy(i->keypairs[kp]->public_key,&packed[ofs],
|
||||||
|
i->keypairs[kp]->private_key_len);
|
||||||
|
ofs+=i->keypairs[kp]->public_key_len;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case KEYTYPE_CRYPTOBOX:
|
case KEYTYPE_CRYPTOBOX:
|
||||||
/* For cryptobox we only need the private key, as we compute the public
|
/* For cryptobox we only need the private key, as we compute the public
|
||||||
key from it when extracting the identity */
|
key from it when extracting the identity */
|
||||||
@ -564,9 +581,12 @@ keyring_identity *keyring_unpack_identity(unsigned char *slot, const char *pin)
|
|||||||
kp->private_key_len=crypto_sign_edwards25519sha512batch_SECRETKEYBYTES;
|
kp->private_key_len=crypto_sign_edwards25519sha512batch_SECRETKEYBYTES;
|
||||||
kp->public_key_len=crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES;
|
kp->public_key_len=crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES;
|
||||||
break;
|
break;
|
||||||
case KEYTYPE_RHIZOME: case KEYTYPE_DID:
|
case KEYTYPE_RHIZOME:
|
||||||
kp->private_key_len=32; kp->public_key_len=0;
|
kp->private_key_len=32; kp->public_key_len=0;
|
||||||
break;
|
break;
|
||||||
|
case KEYTYPE_DID:
|
||||||
|
kp->private_key_len=32; kp->public_key_len=64;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
kp->private_key=malloc(kp->private_key_len);
|
kp->private_key=malloc(kp->private_key_len);
|
||||||
if (!kp->private_key) {
|
if (!kp->private_key) {
|
||||||
@ -601,15 +621,18 @@ keyring_identity *keyring_unpack_identity(unsigned char *slot, const char *pin)
|
|||||||
*/
|
*/
|
||||||
crypto_scalarmult_curve25519_base(kp->public_key,kp->private_key);
|
crypto_scalarmult_curve25519_base(kp->public_key,kp->private_key);
|
||||||
break;
|
break;
|
||||||
|
case KEYTYPE_DID:
|
||||||
case KEYTYPE_CRYPTOSIGN:
|
case KEYTYPE_CRYPTOSIGN:
|
||||||
/* While it is possible to compute the public key from the private key,
|
/* While it is possible to compute the public key from the private key,
|
||||||
NaCl currently does not provide a function to do this, so we have to
|
NaCl currently does not provide a function to do this, so we have to
|
||||||
store it, or else subvert the NaCl API, which I would rather not do.
|
store it, or else subvert the NaCl API, which I would rather not do.
|
||||||
|
So we just copy it out. We use the same code for extracting the
|
||||||
|
public key for a DID (i.e, subscriber name)
|
||||||
*/
|
*/
|
||||||
for(i=0;i<kp->public_key_len;i++) kp->public_key[i]=slot_byte(ofs+i);
|
for(i=0;i<kp->public_key_len;i++) kp->public_key[i]=slot_byte(ofs+i);
|
||||||
ofs+=kp->public_key_len;
|
ofs+=kp->public_key_len;
|
||||||
break;
|
break;
|
||||||
case KEYTYPE_RHIZOME: case KEYTYPE_DID:
|
case KEYTYPE_RHIZOME:
|
||||||
/* no public key value for these, just do nothing */
|
/* no public key value for these, just do nothing */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -760,7 +783,8 @@ int keyring_enter_pin(keyring_file *k, const char *pin)
|
|||||||
The crypto_box and crypto_sign key pairs are automatically created, and the PKR
|
The crypto_box and crypto_sign key pairs are automatically created, and the PKR
|
||||||
is packed and written to a hithero unallocated slot which is then marked full.
|
is packed and written to a hithero unallocated slot which is then marked full.
|
||||||
*/
|
*/
|
||||||
keyring_identity *keyring_create_identity(keyring_file *k,keyring_context *c,char *pin)
|
keyring_identity *keyring_create_identity(keyring_file *k,keyring_context *c,
|
||||||
|
char *pin)
|
||||||
{
|
{
|
||||||
/* Check obvious abort conditions early */
|
/* Check obvious abort conditions early */
|
||||||
if (!k) { WHY("keyring is NULL"); return NULL; }
|
if (!k) { WHY("keyring is NULL"); return NULL; }
|
||||||
@ -845,6 +869,8 @@ keyring_identity *keyring_create_identity(keyring_file *k,keyring_context *c,cha
|
|||||||
WHY("malloc() failed preparing second public key storage");
|
WHY("malloc() failed preparing second public key storage");
|
||||||
goto kci_safeexit;
|
goto kci_safeexit;
|
||||||
}
|
}
|
||||||
|
#warning XXX - Doesnt make sure that public key first nybl is >0 - 1 in 16 identities will be invalid
|
||||||
|
|
||||||
crypto_sign_edwards25519sha512batch_keypair(id->keypairs[1]->public_key,
|
crypto_sign_edwards25519sha512batch_keypair(id->keypairs[1]->public_key,
|
||||||
id->keypairs[1]->private_key);
|
id->keypairs[1]->private_key);
|
||||||
|
|
||||||
@ -964,16 +990,19 @@ int keyring_commit(keyring_file *k)
|
|||||||
return errorCount;
|
return errorCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
int keyring_set_did(keyring_identity *id,char *did)
|
int keyring_set_did(keyring_identity *id,char *did,char *name)
|
||||||
{
|
{
|
||||||
if (!id) return WHY("id is null");
|
if (!id) return WHY("id is null");
|
||||||
if (!did) return WHY("did is null");
|
if (!did) return WHY("did is null");
|
||||||
|
if (!name) name="Mr. Smith";
|
||||||
|
|
||||||
/* Find where to put it */
|
/* Find where to put it */
|
||||||
int i;
|
int i;
|
||||||
for(i=0;i<id->keypair_count;i++)
|
for(i=0;i<id->keypair_count;i++)
|
||||||
if (id->keypairs[i]->type==KEYTYPE_DID)
|
if (id->keypairs[i]->type==KEYTYPE_DID) {
|
||||||
|
WHY("Identity contains DID");
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (i>=PKR_MAX_KEYPAIRS) return WHY("Too many key pairs");
|
if (i>=PKR_MAX_KEYPAIRS) return WHY("Too many key pairs");
|
||||||
|
|
||||||
@ -984,16 +1013,25 @@ int keyring_set_did(keyring_identity *id,char *did)
|
|||||||
id->keypairs[i]->type=KEYTYPE_DID;
|
id->keypairs[i]->type=KEYTYPE_DID;
|
||||||
unsigned char *packedDid=calloc(32,1);
|
unsigned char *packedDid=calloc(32,1);
|
||||||
if (!packedDid) return WHY("calloc() failed");
|
if (!packedDid) return WHY("calloc() failed");
|
||||||
|
unsigned char *packedName=calloc(64,1);
|
||||||
|
if (!packedName) return WHY("calloc() failed");
|
||||||
id->keypairs[i]->private_key=packedDid;
|
id->keypairs[i]->private_key=packedDid;
|
||||||
id->keypairs[i]->private_key_len=32;
|
id->keypairs[i]->private_key_len=32;
|
||||||
|
id->keypairs[i]->public_key=packedName;
|
||||||
|
id->keypairs[i]->public_key_len=64;
|
||||||
id->keypair_count++;
|
id->keypair_count++;
|
||||||
|
WHY("Created DID record for identity");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Store DID unpacked for ease of searching */
|
/* Store DID unpacked for ease of searching */
|
||||||
int len=strlen(did); if (len>31) len=31;
|
int len=strlen(did); if (len>31) len=31;
|
||||||
bcopy(did,&id->keypairs[i]->private_key[0],len);
|
bcopy(did,&id->keypairs[i]->private_key[0],len);
|
||||||
bzero(&id->keypairs[i]->private_key[len],32-len);
|
bzero(&id->keypairs[i]->private_key[len],32-len);
|
||||||
|
len=strlen(name); if (len>63) len=63;
|
||||||
|
bcopy(name,&id->keypairs[i]->public_key[0],len);
|
||||||
|
bzero(&id->keypairs[i]->public_key[len],64-len);
|
||||||
dump("storing did",&id->keypairs[i]->private_key[0],32);
|
dump("storing did",&id->keypairs[i]->private_key[0],32);
|
||||||
|
dump("storing name",&id->keypairs[i]->public_key[0],64);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1344,14 +1382,15 @@ int keyring_seed(keyring_file *k)
|
|||||||
unsigned char did[65];
|
unsigned char did[65];
|
||||||
/* Securely generate random telephone number */
|
/* Securely generate random telephone number */
|
||||||
urandombytes((unsigned char *)did,10);
|
urandombytes((unsigned char *)did,10);
|
||||||
/* Make DID start with 2 through 9, as 1 is special in many number spaces. */
|
/* Make DID start with 2 through 9, as 1 is special in many number spaces,
|
||||||
|
and 0 is commonly used for escaping to national or international dialling. */
|
||||||
did[0]='2'+(did[0]%8);
|
did[0]='2'+(did[0]%8);
|
||||||
/* Then add 10 more digits, which is what we do in the mobile phone software */
|
/* Then add 10 more digits, which is what we do in the mobile phone software */
|
||||||
for(i=1;i<11;i++) did[i]='0'+(did[i]%10); did[11]=0;
|
for(i=1;i<11;i++) did[i]='0'+(did[i]%10); did[11]=0;
|
||||||
|
|
||||||
keyring_identity *id=keyring_create_identity(k,k->contexts[0],"");
|
keyring_identity *id=keyring_create_identity(k,k->contexts[0],"");
|
||||||
if (!id) return WHY("Could not create new identity");
|
if (!id) return WHY("Could not create new identity");
|
||||||
if (keyring_set_did(id,(char *)did)) return WHY("Could not set DID of new identity");
|
if (keyring_set_did(id,(char *)did,"")) return WHY("Could not set DID of new identity");
|
||||||
if (keyring_commit(k)) return WHY("Could not commit new identity to keyring file");
|
if (keyring_commit(k)) return WHY("Could not commit new identity to keyring file");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -493,8 +493,9 @@ int overlay_saw_mdp_frame(int interface, overlay_mdp_frame *mdp,long long now)
|
|||||||
while(keyring_find_did(keyring,&cn,&in,&kp,did))
|
while(keyring_find_did(keyring,&cn,&in,&kp,did))
|
||||||
{
|
{
|
||||||
WHYF("Found matching did");
|
WHYF("Found matching did");
|
||||||
/* package DID plus SID into reply (we include the DID because
|
/* package DID and Name into reply (we include the DID because
|
||||||
it could be a wild-card DID search). */
|
it could be a wild-card DID search, but the SID is implied
|
||||||
|
in the source address of our reply). */
|
||||||
if (keyring->contexts[cn]->identities[in]->keypairs[kp]
|
if (keyring->contexts[cn]->identities[in]->keypairs[kp]
|
||||||
->private_key_len>64)
|
->private_key_len>64)
|
||||||
/* skip excessively long DID records */
|
/* skip excessively long DID records */
|
||||||
@ -507,10 +508,20 @@ int overlay_saw_mdp_frame(int interface, overlay_mdp_frame *mdp,long long now)
|
|||||||
->private_key,&mdp->out.payload[0],
|
->private_key,&mdp->out.payload[0],
|
||||||
keyring->contexts[cn]->identities[in]->keypairs[kp]
|
keyring->contexts[cn]->identities[in]->keypairs[kp]
|
||||||
->private_key_len);
|
->private_key_len);
|
||||||
|
bcopy(keyring->contexts[cn]->identities[in]->keypairs[kp]
|
||||||
|
->public_key,&mdp->out.payload[keyring
|
||||||
|
->contexts[cn]
|
||||||
|
->identities[in]
|
||||||
|
->keypairs[kp]
|
||||||
|
->private_key_len],
|
||||||
|
keyring->contexts[cn]->identities[in]->keypairs[kp]
|
||||||
|
->private_key_len);
|
||||||
/* set length */
|
/* set length */
|
||||||
mdp->out.payload_length=
|
mdp->out.payload_length=
|
||||||
keyring->contexts[cn]->identities[in]->keypairs[kp]
|
keyring->contexts[cn]->identities[in]->keypairs[kp]
|
||||||
->private_key_len;
|
->private_key_len
|
||||||
|
+keyring->contexts[cn]->identities[in]->keypairs[kp]
|
||||||
|
->public_key_len;
|
||||||
/* mark as outgoing MDP message */
|
/* mark as outgoing MDP message */
|
||||||
mdp->packetTypeAndFlags&=MDP_FLAG_MASK;
|
mdp->packetTypeAndFlags&=MDP_FLAG_MASK;
|
||||||
mdp->packetTypeAndFlags|=MDP_TX;
|
mdp->packetTypeAndFlags|=MDP_TX;
|
||||||
|
@ -1368,6 +1368,12 @@ int overlay_route_node_info(overlay_mdp_frame *mdp,
|
|||||||
&mdp->nodeinfo.did[0],
|
&mdp->nodeinfo.did[0],
|
||||||
keyring->contexts[cn]->identities[in]
|
keyring->contexts[cn]->identities[in]
|
||||||
->keypairs[k2]->private_key_len);
|
->keypairs[k2]->private_key_len);
|
||||||
|
/* public key has name */
|
||||||
|
bcopy(&keyring->contexts[cn]->identities[in]
|
||||||
|
->keypairs[k2]->public_key[0],
|
||||||
|
&mdp->nodeinfo.name[0],
|
||||||
|
keyring->contexts[cn]->identities[in]
|
||||||
|
->keypairs[k2]->public_key_len);
|
||||||
mdp->nodeinfo.resolve_did=1;
|
mdp->nodeinfo.resolve_did=1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
3
serval.h
3
serval.h
@ -241,7 +241,7 @@ keyring_file *keyring_open(char *file);
|
|||||||
keyring_file *keyring_open_with_pins(const char *pinlist);
|
keyring_file *keyring_open_with_pins(const char *pinlist);
|
||||||
int keyring_enter_pin(keyring_file *k, const char *pin);
|
int keyring_enter_pin(keyring_file *k, const char *pin);
|
||||||
int keyring_enter_pins(keyring_file *k, const char *pinlist);
|
int keyring_enter_pins(keyring_file *k, const char *pinlist);
|
||||||
int keyring_set_did(keyring_identity *id,char *did);
|
int keyring_set_did(keyring_identity *id,char *did,char *name);
|
||||||
int keyring_sanitise_position(keyring_file *k,int *cn,int *in,int *kp);
|
int keyring_sanitise_position(keyring_file *k,int *cn,int *in,int *kp);
|
||||||
int keyring_next_identity(keyring_file *k,int *cn,int *in,int *kp);
|
int keyring_next_identity(keyring_file *k,int *cn,int *in,int *kp);
|
||||||
int keyring_find_did(keyring_file *k,int *cn,int *in,int *kp,char *did);
|
int keyring_find_did(keyring_file *k,int *cn,int *in,int *kp,char *did);
|
||||||
@ -1198,6 +1198,7 @@ typedef struct overlay_mdp_nodeinfo {
|
|||||||
unsigned char sid[SID_SIZE];
|
unsigned char sid[SID_SIZE];
|
||||||
int sid_prefix_length; /* allow wildcard matching */
|
int sid_prefix_length; /* allow wildcard matching */
|
||||||
char did[64];
|
char did[64];
|
||||||
|
char name[64];
|
||||||
int foundP;
|
int foundP;
|
||||||
int localP;
|
int localP;
|
||||||
int neighbourP;
|
int neighbourP;
|
||||||
|
2
server.c
2
server.c
@ -195,7 +195,7 @@ int processRequest(unsigned char *packet,int len,
|
|||||||
/* Creating an identity is nice and easy now with the new keyring */
|
/* Creating an identity is nice and easy now with the new keyring */
|
||||||
keyring_identity *id=keyring_create_identity(keyring,keyring->contexts[0],
|
keyring_identity *id=keyring_create_identity(keyring,keyring->contexts[0],
|
||||||
"");
|
"");
|
||||||
if (id) keyring_set_did(id,did);
|
if (id) keyring_set_did(id,did,"Mr. Smith");
|
||||||
if (id==NULL||keyring_commit(keyring))
|
if (id==NULL||keyring_commit(keyring))
|
||||||
return respondSimple(NULL,ACTION_DECLINED,NULL,0,transaction_id,recvttl,
|
return respondSimple(NULL,ACTION_DECLINED,NULL,0,transaction_id,recvttl,
|
||||||
sender,CRYPT_CIPHERED|CRYPT_SIGNED);
|
sender,CRYPT_CIPHERED|CRYPT_SIGNED);
|
||||||
|
Loading…
Reference in New Issue
Block a user