diff options
author | vi117747 <none@none> | 2006-10-07 14:26:26 -0700 |
---|---|---|
committer | vi117747 <none@none> | 2006-10-07 14:26:26 -0700 |
commit | 40cb5e5daa7b80bb70fcf8dadfb20f9281566331 (patch) | |
tree | dc95663e296c5dbf3cb8faa561e53416978eb4dc /usr/src/lib/libsip/common/sip_gids.c | |
parent | 56a424cca6b3f91f31bdab72a4626c48c779fe8b (diff) | |
download | illumos-gate-40cb5e5daa7b80bb70fcf8dadfb20f9281566331.tar.gz |
PSARC 2006/402 SIP Library Integration
6461142 Integrate SIP in Solaris
Diffstat (limited to 'usr/src/lib/libsip/common/sip_gids.c')
-rw-r--r-- | usr/src/lib/libsip/common/sip_gids.c | 302 |
1 files changed, 302 insertions, 0 deletions
diff --git a/usr/src/lib/libsip/common/sip_gids.c b/usr/src/lib/libsip/common/sip_gids.c new file mode 100644 index 0000000000..f1ecfd726b --- /dev/null +++ b/usr/src/lib/libsip/common/sip_gids.c @@ -0,0 +1,302 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> +#include <unistd.h> +#include <errno.h> +#include <sys/types.h> +#include <time.h> +#include <sys/errno.h> +#ifdef __linux__ +#include <sasl/sasl.h> +#include <sasl/saslplug.h> +#else +#include <sys/md5.h> +#endif + +#include "sip_parse_uri.h" +#include "sip_msg.h" +#include "sip_miscdefs.h" + +void sip_md5_hash(char *, int, char *, int, char *, int, char *, int, + char *, int, char *, int, uchar_t *); + +#define SIP_RANDOM_LEN 20 + +/* + * Wrapper around /dev/urandom + */ +static int +sip_get_random(char *buf, int buflen) +{ + static int devrandom = -1; + + if (devrandom == -1 && + (devrandom = open("/dev/urandom", O_RDONLY)) == -1) { + return (-1); + } + + if (read(devrandom, buf, buflen) == -1) + return (-1); + return (0); +} + +/* + * Get MD5 hash of call_id, from_tag, to_tag using key + */ +void +sip_md5_hash(char *str1, int lstr1, char *str2, int lstr2, char *str3, + int lstr3, char *str4, int lstr4, char *str5, int lstr5, + char *str6, int lstr6, uchar_t *digest) +{ + MD5_CTX ctx; + +#ifdef __linux__ + _sasl_MD5Init(&ctx); + + _sasl_MD5Update(&ctx, (uchar_t *)&sip_hash_salt, sizeof (uint64_t)); + + if (str1 != NULL) + _sasl_MD5Update(&ctx, (uchar_t *)str1, lstr1); + + if (str2 != NULL) + _sasl_MD5Update(&ctx, (uchar_t *)str2, lstr2); + + if (str3 != NULL) + _sasl_MD5Update(&ctx, (uchar_t *)str3, lstr3); + + if (str4 != NULL) + _sasl_MD5Update(&ctx, (uchar_t *)str4, lstr4); + + if (str5 != NULL) + _sasl_MD5Update(&ctx, (uchar_t *)str5, lstr5); + + if (str6 != NULL) + _sasl_MD5Update(&ctx, (uchar_t *)str6, lstr6); + + _sasl_MD5Final(digest, &ctx); +#else /* solaris */ + MD5Init(&ctx); + + MD5Update(&ctx, (uchar_t *)&sip_hash_salt, sizeof (uint64_t)); + + if (str1 != NULL) + MD5Update(&ctx, (uchar_t *)str1, lstr1); + + if (str2 != NULL) + MD5Update(&ctx, (uchar_t *)str2, lstr2); + + if (str3 != NULL) + MD5Update(&ctx, (uchar_t *)str3, lstr3); + + if (str4 != NULL) + MD5Update(&ctx, (uchar_t *)str4, lstr4); + + if (str5 != NULL) + MD5Update(&ctx, (uchar_t *)str5, lstr5); + + if (str6 != NULL) + MD5Update(&ctx, (uchar_t *)str6, lstr6); + + MD5Final(digest, &ctx); +#endif +} + +/* + * generate a guid (globally unique id) + */ +char * +sip_guid() +{ + int i; + uint8_t *r; + uint32_t random; + uint32_t time; + char *guid; + int guidlen; +#ifdef __linux__ + struct timespec tspec; +#endif + + guid = (char *)malloc(SIP_RANDOM_LEN + 1); + if (guid == NULL) + return (NULL); + /* + * Get a 32-bit random # + */ + if (sip_get_random((char *)&random, sizeof (random)) != 0) + return (NULL); +#ifdef __linux__ + if (clock_gettime(CLOCK_REALTIME, &tspec) != 0) + return (NULL); + time = (uint32_t)tspec.tv_nsec; +#else + /* + * Get 32-bits from gethrtime() + */ + time = (uint32_t)gethrtime(); +#endif + (void) snprintf(guid, SIP_RANDOM_LEN + 1, "%u%u", random, time); + guidlen = strlen(guid); + + /* + * just throw in some alphabets too + */ + r = (uint8_t *)malloc(guidlen); + if (sip_get_random((char *)r, guidlen) != 0) { + free(guid); + return (NULL); + } + for (i = 0; i < guidlen; i++) { + if ((r[i] >= 65 && r[i] <= 90) || + (r[i] >= 97 && r[i] <= 122)) { + guid[i] = r[i]; + } + } + free(r); + return (guid); +} + +/* + * Generate branchid for a transaction + */ +char * +sip_branchid(sip_msg_t sip_msg) +{ + char *guid; + char *branchid; + _sip_header_t *via; + unsigned char md5_hash[16]; + _sip_header_t *to; + _sip_header_t *from; + _sip_header_t *callid; + _sip_msg_t *_sip_msg; + int cseq; + MD5_CTX ctx; + size_t len; + int hdrlen; + int i; + + if (sip_msg == NULL) { +generate_bid: + if ((branchid = (char *)malloc(SIP_BRANCHID_LEN + 1)) == NULL) + return (NULL); + guid = sip_guid(); + if (guid == NULL) { + free(branchid); + return (NULL); + } + (void) snprintf(branchid, SIP_BRANCHID_LEN + 1, "z9hG4bK%s", + guid); + free(guid); + return (branchid); + } + _sip_msg = (_sip_msg_t *)sip_msg; + (void) pthread_mutex_lock(&_sip_msg->sip_msg_mutex); + via = sip_search_for_header(_sip_msg, SIP_VIA, NULL); + if (via == NULL) { + (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); + goto generate_bid; + } + to = sip_search_for_header(_sip_msg, SIP_TO, NULL); + from = sip_search_for_header(_sip_msg, SIP_FROM, NULL); + callid = sip_search_for_header(_sip_msg, SIP_CALL_ID, NULL); + (void) pthread_mutex_unlock(&_sip_msg->sip_msg_mutex); + cseq = sip_get_callseq_num(_sip_msg, NULL); + if (to == NULL || from == NULL || callid == NULL || cseq == -1) + return (NULL); + if (_sip_msg->sip_msg_req_res == NULL || + _sip_msg->sip_msg_req_res->U.sip_request.sip_request_uri. + sip_str_ptr == NULL) { + return (NULL); + } + len = 2 * sizeof (md5_hash) + 1; + if ((branchid = malloc(len)) == NULL) + return (NULL); +#ifdef __linux__ + _sasl_MD5Init(&ctx); + hdrlen = via->sip_hdr_end - via->sip_hdr_start; + _sasl_MD5Update(&ctx, (uchar_t *)via->sip_hdr_start, hdrlen); + hdrlen = to->sip_hdr_end - to->sip_hdr_start; + _sasl_MD5Update(&ctx, (uchar_t *)to->sip_hdr_start, hdrlen); + hdrlen = from->sip_hdr_end - from->sip_hdr_start; + _sasl_MD5Update(&ctx, (uchar_t *)from->sip_hdr_start, hdrlen); + hdrlen = callid->sip_hdr_end - callid->sip_hdr_start; + _sasl_MD5Update(&ctx, (uchar_t *)callid->sip_hdr_start, hdrlen); + _sasl_MD5Update(&ctx, (uchar_t *)_sip_msg->sip_msg_req_res-> + U.sip_request.sip_request_uri.sip_str_ptr, + _sip_msg->sip_msg_req_res->U.sip_request. + sip_request_uri.sip_str_len); + _sasl_MD5Update(&ctx, (uchar_t *)&cseq, sizeof (int)); + _sasl_MD5Final(md5_hash, &ctx); +#else /* solaris */ + MD5Init(&ctx); + hdrlen = via->sip_hdr_end - via->sip_hdr_start; + MD5Update(&ctx, (uchar_t *)via->sip_hdr_start, hdrlen); + hdrlen = to->sip_hdr_end - to->sip_hdr_start; + MD5Update(&ctx, (uchar_t *)to->sip_hdr_start, hdrlen); + hdrlen = from->sip_hdr_end - from->sip_hdr_start; + MD5Update(&ctx, (uchar_t *)from->sip_hdr_start, hdrlen); + hdrlen = callid->sip_hdr_end - callid->sip_hdr_start; + MD5Update(&ctx, (uchar_t *)callid->sip_hdr_start, hdrlen); + MD5Update(&ctx, (uchar_t *)_sip_msg->sip_msg_req_res-> + U.sip_request.sip_request_uri.sip_str_ptr, + _sip_msg->sip_msg_req_res->U.sip_request. + sip_request_uri.sip_str_len); + MD5Update(&ctx, (uchar_t *)&cseq, sizeof (int)); + MD5Final(md5_hash, &ctx); +#endif + for (i = 0; i < sizeof (md5_hash); i++) { + (void) snprintf(&branchid[2 * i], len - (2 * i), "%02x", + md5_hash[i]); + } + return (branchid); +} + +uint32_t +sip_get_cseq() +{ + time_t tval; + + tval = time(NULL); + + return ((uint32_t)tval); +} + +uint32_t +sip_get_rseq() +{ + time_t tval; + + tval = time(NULL); + + return ((uint32_t)tval); +} |