diff --git a/commandline.c b/commandline.c index 5a55844b..0761a7cc 100644 --- a/commandline.c +++ b/commandline.c @@ -496,11 +496,12 @@ int app_dna_lookup(int argc, const char *const *argv, struct command_line_option else if ((rx.packetTypeAndFlags&MDP_TYPE_MASK)==MDP_TX) { /* Extract DID, Name, URI from response. */ if (strlen((char *)rx.in.payload)<512) { + char sidhex[512]; char did[512]; char name[512]; char uri[512]; if (!parseDnaReply(rx.in.payload,rx.in.payload_length, - did,name,uri)) + sidhex,did,name,uri)) { /* Have we seen this response before? */ int i; @@ -1805,11 +1806,12 @@ int app_node_info(int argc, const char *const *argv, struct command_line_option } { + char sidhex[512]; char did[512]; char name[512]; char uri[512]; if (!parseDnaReply(m2.in.payload,m2.in.payload_length, - did,name,uri)) + sidhex,did,name,uri)) { /* Got a good DNA reply, copy it into place */ bcopy(did,mdp.nodeinfo.did,32); diff --git a/dna_helper.c b/dna_helper.c index cb7b94bd..2391961c 100644 --- a/dna_helper.c +++ b/dna_helper.c @@ -42,26 +42,47 @@ static int dna_helper_stdin = -1; static int dna_helper_stdout = -1; int -parseDnaReply(unsigned char *bytes, int count, char *did, char *name, char *uri) { +parseDnaReply(unsigned char *bytes, int count, + char *sidhex, char *did, char *name, char *uri) { + bzero(sidhex, SID_SIZE*2+1); bzero(did, SID_SIZE); bzero(name,64); bzero(uri,512); - int i,l; + int i,l,maxlen; l=0; - for(i=0;i<511&&i=count||i>=511) return WHY("DNA response does not contain name field"); - l=0; i++; - for(;i<511&&i=count||i>=511) return WHY("DNA response does not contain URI field"); - l=0; i++; - for(;i<511&&i=count) return WHY("DNA helper response does not contain URI field"); + if (l>=maxlen) return WHY("DNA helper response SID field too long"); + l=0; i++; maxlen=511; + for(;l=count) return WHY("DNA helper response does not contain DID field"); + if (l>=maxlen) return WHY("DNA helper response URI field too long"); + l=0; i++; maxlen=SID_SIZE; + for(;l=count) return WHY("DNA helper response does not contain CALLERID field"); + if (l>=maxlen) return WHY("DNA helper response DID field too long"); + l=0; i++; maxlen=SID_SIZE; + for(;l=count) return WHY("DNA helper response does not contain terminator"); + if (l>=maxlen) return WHY("DNA helper response CALLERID field too long"); + /* DEBUGF("did='%s', name='%s', uri='%s'",did,name,uri); */ return 0; diff --git a/overlay_mdp.c b/overlay_mdp.c index 65947b5b..9925a239 100644 --- a/overlay_mdp.c +++ b/overlay_mdp.c @@ -561,9 +561,10 @@ int overlay_saw_mdp_frame(overlay_mdp_frame *mdp,long long now) /* copy SID out into source address of frame */ bcopy(packedSid,&mdpreply.out.src.sid[0],SID_SIZE); /* and build reply as did\nname\nURI */ - snprintf((char *)&mdpreply.out.payload[0],512,"%s\n%s\nsid://%s/%s", - unpackedDid,name,overlay_render_sid(packedSid), - unpackedDid); + snprintf((char *)&mdpreply.out.payload[0],512,"%s|sid://%s/%s|%s|%s|", + overlay_render_sid(packedSid), + overlay_render_sid(packedSid),unpackedDid, + unpackedDid,name); mdpreply.out.payload_length=strlen((char *)mdpreply.out.payload)+1; /* deliver reply */ diff --git a/serval.h b/serval.h index ae7e2786..f3b6b6ae 100755 --- a/serval.h +++ b/serval.h @@ -1539,9 +1539,8 @@ int server_probe(int *pid); int dna_helper_enqueue(char *did, unsigned char *requestorSid); int dna_return_resolution(overlay_mdp_frame *mdp, unsigned char *fromSid, const char *did,const char *name,const char *uri); -int parseDnaReply(unsigned char *bytes,int count, - char *did,char *name,char *uri); - +int parseDnaReply(unsigned char *bytes, int count, + char *sidhex, char *did, char *name, char *uri); extern int sigPipeFlag; extern int sigIoFlag; void sigPipeHandler(int signal); diff --git a/tests/dnahelper b/tests/dnahelper new file mode 100755 index 00000000..51e89a7c --- /dev/null +++ b/tests/dnahelper @@ -0,0 +1,225 @@ +#!/bin/bash + +# Tests for Serval DNA server operations. +# +# Copyright 2012 Paul Gardner-Stephen +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +source "${0%/*}/../testframework.sh" +source "${0%/*}/../testdefs.sh" + +setup() { + setup_servald + assert_no_servald_processes +} + +teardown() { +# TODO Disabled until stopping multiple-instances are supported +# TODO stop_all_servald_servers + kill_all_servald_processes + assert_no_servald_processes +} + +setup_servald_instance() { + cat > $SERVALINSTANCE_PATH/dnahelper <$2" + executeOk_servald config set dna.helper "$SERVALINSTANCE_PATH/dnahelper" + executeOk_servald config set monitor.socket "org.servalproject.servald.monitor.socket.$1" + executeOk_servald config set mdp.socket "org.servalproject.servald.mdp.socket.$1" + executeOk_servald keyring add + assert [ -e "$SERVALINSTANCE_PATH/serval.keyring" ] + executeOk_servald keyring list + tfw_cat --stdout + sid=$(replayStdout | sed -ne "1s/^\($rexp_sid\):.*\$/\1/p") + assert --message='main identity known' [ -n "$sid" ] + executeOk_servald set did $sid 5550001 "Agent $instance_name Smith" + start_servald_server + executeOk_servald status + tfw_cat --stdout + pop_instance +} + +setup_servald_instances() { + setup_servald + DUMMYNET=`pwd`/dummy.dat + rm $DUMMYNET + touch $DUMMYNET + assert [ -e $DUMMYNET ] + setup_servald_instance +A $DUMMYNET + SIDA=$sid + setup_servald_instance +B $DUMMYNET + SIDB=$sid + # Now make sure that they can see each other + sleep 10 # Should be plenty of time + set_instance +A + echo "Dummynet file $DUMMYNET after 5 seconds: "`ls -l $DUMMYNET` + executeOk_servald id peers + assertStdoutLineCount '==' 1 +} + +doc_MultipleServalDTest="Start two servald instances with dummy interface" + +setup_MultipleServalDTest() { + setup +} + +test_MultipleServalDTest() { + setup_servald_instances +} + +doc_DNAWildcardSearchFindsSelf="DNA lookup of wildcard finds (star method)" +setup_DNAWildcardSearchFindsSelf() { + setup + setup_servald_instances + set_instance +A +} +test_DNAWildcardSearchFindsSelf() { + executeOk_servald dna lookup "*" + assertStdoutLineCount '==' 2 + assertStdoutGrep --matches=1 "^sid://$SIDA/5550001:5550001:Agent A Smith$" + assertStdoutGrep --matches=1 "^sid://$SIDB/5550001:5550001:Agent B Smith$" +} + +doc_DNAWildcardSearchFindsSelfEmpty="DNA lookup of wildcard (empty query method)" +setup_DNAWildcardSearchFindsSelfEmpty() { + setup + setup_servald_instances + set_instance +A +} +test_DNAWildcardSearchFindsSelfEmpty() { + executeOk_servald dna lookup "" + assertStdoutLineCount '==' 2 + assertStdoutGrep --matches=1 "^sid://$SIDA/5550001:5550001:Agent A Smith$" + assertStdoutGrep --matches=1 "^sid://$SIDB/5550001:5550001:Agent B Smith$" +} + +doc_DNASpecificLookup="DNA Lookup by phone number" +setup_DNASpecificLookup() { + setup + setup_servald_instances + set_instance +A +} +test_DNASpecificLookup() { + # Make sure we get no false positives + executeOk_servald dna lookup "5551234" + assertStdoutLineCount '==' 0 + executeOk_servald dna lookup "555000" + assertStdoutLineCount '==' 0 + executeOk_servald dna lookup "55500011" + assertStdoutLineCount '==' 0 + # Make sure we get the right results, and no duplicates + executeOk_servald dna lookup "5550001" + assertStdoutLineCount '==' 2 + assertStdoutGrep --matches=1 "^sid://$SIDA/5550001:5550001:Agent A Smith$" + assertStdoutGrep --matches=1 "^sid://$SIDB/5550001:5550001:Agent B Smith$" +} + +doc_DNANodeInfoLocalResolution="'node info' auto-resolves for local identities" +setup_DNANodeInfoLocalResolution() { + setup + setup_servald_instances + set_instance +A +} +test_DNANodeInfoLocalResolution() { + # node info for a local identity returns DID/Name since it is free, even + # if it isn't asked for. + executeOk_servald node info $SIDA + assertStdoutLineCount '==' 1 + assertStdoutGrep --matches=1 "Agent A Smith" + assertStdoutGrep --matches=0 "did-not-resolved" +} + +doc_DNANodeInfoRemoteResolution="'node info' for remote identities" +setup_DNANodeInfoRemoteResolution() { + setup + setup_servald_instances + set_instance +A +} +test_DNANodeInfoRemoteResolution() { + # if resolvedid is not specified for a remote identity, then don't resolve + # it. + executeOk_servald node info $SIDB + assertStdoutLineCount '==' 1 + assertStdoutGrep --matches=0 "Agent B Smith" + assertStdoutGrep --matches=1 "did-not-resolved" + + # But if it resolvedid is specified, then do resolve it using DNA + executeOk_servald node info $SIDB resolvedid + assertStdoutLineCount '==' 1 + assertStdoutGrep --matches=1 "Agent B Smith" + assertStdoutGrep --matches=0 "did-not-resolved" + +} + + +runTests "$@"