Module: sip-router
Branch: pd/outbound
Commit: 1db38af24d8808a9a2045c7bac25581199717a2b
URL:    
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=1db38af24d8808a9a2045c7bac25581199717a2b

Author: Peter Dunkley <[email protected]>
Committer: Peter Dunkley <[email protected]>
Date:   Sat Dec 22 13:07:58 2012 +0000

modules_k/outbound: Filled in functions to encode and decode flow tokens

---

 modules_k/outbound/Makefile |    2 +-
 modules_k/outbound/ob_mod.c |  108 ++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 108 insertions(+), 2 deletions(-)

diff --git a/modules_k/outbound/Makefile b/modules_k/outbound/Makefile
index 148a900..e877c04 100644
--- a/modules_k/outbound/Makefile
+++ b/modules_k/outbound/Makefile
@@ -18,7 +18,7 @@ else
        LIBS=  $(shell pkg-config --libs libssl)
 endif
 
-DEFS+=-DOPENSER_MOD_INTERFACE
+DEFS+=-DKAMAILIO_MOD_INTERFACE
 
 SERLIBPATH=../../lib
 SER_LIBS+=$(SERLIBPATH)/kcore/kcore
diff --git a/modules_k/outbound/ob_mod.c b/modules_k/outbound/ob_mod.c
index fbbee03..63e922f 100644
--- a/modules_k/outbound/ob_mod.c
+++ b/modules_k/outbound/ob_mod.c
@@ -20,7 +20,9 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  */
+#include <openssl/hmac.h>
 
+#include "../../basex.h"
 #include "../../dprint.h"
 #include "../../dset.h"
 #include "../../ip_addr.h"
@@ -90,14 +92,118 @@ static int mod_init(void)
        return 0;
 }
 
+/* Structure of flow token
+
+   <HMAC-SHA1-80><protocol><dst_ip><dst_port><src_ip><src_port>
+          10     +    1    +  16   +    2    +  16   +    2
+          = 47 bytes
+
+   IP addresses will always be 16 bytes. When an IPv4 address is used the
+   address will be encoded in the first four bytes and the last four bytes will
+   be ignored.
+
+   base64 encoded size: ceiling((47+2)/3)*4 = 68 bytes
+*/
+
+#define UNENC_FLOW_TOKEN_LENGTH        47
+#define SHA1_LENGTH            20
+#define SHA1_80_LENGTH         10
+#define FLOW_TOKEN_START_POS   (SHA1_80_LENGTH)
+static unsigned char unenc_flow_token[UNENC_FLOW_TOKEN_LENGTH];
+static unsigned char hmac_sha1[EVP_MAX_MD_SIZE];
+
 int encode_flow_token(str *flow_token, struct receive_info rcv)
 {
-       
+       int pos = FLOW_TOKEN_START_POS, i;
+
+       if (flow_token == NULL)
+       {
+               LM_ERR("bad string pointer\n");
+               return -1;
+       }
+
+       /* Encode protocol information */
+       unenc_flow_token[pos++] = rcv.proto;
+
+       /* Encode destination address */
+       for (i = 0; i < 16; i++)
+               unenc_flow_token[pos++] = rcv.dst_ip.u.addr[i];
+       unenc_flow_token[pos++] = (rcv.dst_port >> 8) & 0xff;
+       unenc_flow_token[pos++] =  rcv.dst_port       & 0xff;
+
+       /* Encode source address */
+       for (i = 0; i < 16; i++)
+               unenc_flow_token[pos++] = rcv.src_ip.u.addr[i];
+       unenc_flow_token[pos++] = (rcv.dst_port >> 8) & 0xff;
+       unenc_flow_token[pos++] =  rcv.dst_port       & 0xff;
+
+       /* HMAC-SHA1 the calculated flow token, truncate to 80 bits, and
+          prepend onto the flow token */
+       HMAC(EVP_sha1(), ob_key.s, ob_key.len,
+               &unenc_flow_token[FLOW_TOKEN_START_POS],
+               UNENC_FLOW_TOKEN_LENGTH - FLOW_TOKEN_START_POS,
+               hmac_sha1, NULL);
+       memcpy(unenc_flow_token, &hmac_sha1[SHA1_LENGTH - SHA1_80_LENGTH],
+               SHA1_80_LENGTH);
+
+       /* base64 encode the entire flow token and store for the caller to
+          use */
+       flow_token->s = pkg_malloc(base64_enc_len(UNENC_FLOW_TOKEN_LENGTH));
+       if (flow_token->s == NULL)
+       {
+               LM_ERR("allocating package memory\n");
+               return -1;
+       }
+       flow_token->len = base64_enc(unenc_flow_token, UNENC_FLOW_TOKEN_LENGTH,
+                               (unsigned char *) flow_token->s,
+                               base64_enc_len(UNENC_FLOW_TOKEN_LENGTH));
+
        return 0;
 }
 
 int decode_flow_token(struct receive_info *rcv, str flow_token)
 {
+       int pos = FLOW_TOKEN_START_POS, i;
+
+       if (flow_token.len != base64_enc_len(UNENC_FLOW_TOKEN_LENGTH))
+       {
+               LM_ERR("bad flow token length.  Length is %d, expected %d\n",
+                       flow_token.len, UNENC_FLOW_TOKEN_LENGTH);
+               return -1;
+       }
+
+       /* base64 decode the flow token */
+       base64_dec((unsigned char *) flow_token.s, flow_token.len,
+                       unenc_flow_token, UNENC_FLOW_TOKEN_LENGTH);
+
+       /* HMAC-SHA1 the flow token (after the hash) and compare with the
+          truncated hash at the start of the flow token. */
+       HMAC(EVP_sha1(), ob_key.s, ob_key.len,
+               &unenc_flow_token[FLOW_TOKEN_START_POS],
+               UNENC_FLOW_TOKEN_LENGTH - FLOW_TOKEN_START_POS,
+               hmac_sha1, NULL);
+       if (memcmp(unenc_flow_token, &hmac_sha1[SHA1_LENGTH - SHA1_80_LENGTH],
+               SHA1_80_LENGTH) != 0)
+       {
+               LM_ERR("flow token failed validation\n");
+               return -1;
+       }
+
+       /* Decode protocol information */
+       rcv->proto = unenc_flow_token[pos++];
+
+       /* Decode destination address */
+       for (i = 0; i < 16; i++)
+               rcv->dst_ip.u.addr[i] = unenc_flow_token[pos++];
+       rcv->dst_port = ((unenc_flow_token[pos++] << 8) & 0xff)
+                               | (unenc_flow_token[pos++] & 0xff);
+
+       /* Decode source address */
+       for (i = 0; i < 16; i++)
+               rcv->src_ip.u.addr[i] = unenc_flow_token[pos++];
+       rcv->src_port = ((unenc_flow_token[pos++] << 8) & 0xff)
+                               | (unenc_flow_token[pos++] & 0xff);
+
        return 0;
 }
 


_______________________________________________
sr-dev mailing list
[email protected]
http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev

Reply via email to