aboutsummaryrefslogtreecommitdiffstats
path: root/res/res_osp.c
diff options
context:
space:
mode:
authormogorman <mogorman@f38db490-d61c-443f-a65b-d21fe96a405b>2006-06-30 15:12:35 +0000
committermogorman <mogorman@f38db490-d61c-443f-a65b-d21fe96a405b>2006-06-30 15:12:35 +0000
commit1f7cdb4f1d12768ce50aa4d2ced5012f4989d3fd (patch)
tree4fb1b700a71f812a07d2e892c5c9f2092049ab80 /res/res_osp.c
parentc378273d190aeeab364399b1e9460e027331a250 (diff)
Updates from transnexus to osplookup, removes res_osp
and puts all logic into the app, documentation provided now in osp.txt. git-svn-id: http://svn.digium.com/svn/asterisk/trunk@36406 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'res/res_osp.c')
-rw-r--r--res/res_osp.c1114
1 files changed, 0 insertions, 1114 deletions
diff --git a/res/res_osp.c b/res/res_osp.c
deleted file mode 100644
index 62115db4b..000000000
--- a/res/res_osp.c
+++ /dev/null
@@ -1,1114 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2006, Digium, Inc.
- *
- * Mark Spencer <markster@digium.com>
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*!
- * \file
- * \brief Provide Open Settlement Protocol capability
- *
- * \author Mark Spencer <markster@digium.com>
- *
- * \arg See also: \ref app_osplookup.c
- */
-
-/*** MODULEINFO
- <depend>libosptk</depend>
- <depend>ssl</depend>
- ***/
-
-#include "asterisk.h"
-
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-
-#include <sys/types.h>
-#include <osp/osp.h>
-#include <osp/osputils.h>
-#include <openssl/err.h>
-#include <stdio.h>
-#include <dirent.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <openssl/bio.h>
-#include <openssl/pem.h>
-#include <openssl/evp.h>
-
-#include "asterisk/file.h"
-#include "asterisk/channel.h"
-#include "asterisk/logger.h"
-#include "asterisk/say.h"
-#include "asterisk/module.h"
-#include "asterisk/options.h"
-#include "asterisk/crypto.h"
-#include "asterisk/md5.h"
-#include "asterisk/cli.h"
-#include "asterisk/io.h"
-#include "asterisk/lock.h"
-#include "asterisk/astosp.h"
-#include "asterisk/config.h"
-#include "asterisk/utils.h"
-#include "asterisk/lock.h"
-#include "asterisk/causes.h"
-#include "asterisk/callerid.h"
-#include "asterisk/pbx.h"
-
-/* OSP Authentication Policy */
-enum osp_authpolicy {
- OSP_AUTH_NO,
- OSP_AUTH_YES,
- OSP_AUTH_EXCLUSIVE
-};
-
-#define OSP_CONFIG_FILE ((char*)"osp.conf")
-#define OSP_GENERAL_CAT ((char*)"general")
-#define OSP_MAX_CERTS ((unsigned int)10)
-#define OSP_MAX_SRVS ((unsigned int)10)
-#define OSP_DEF_MAXCONNECTIONS ((unsigned int)20)
-#define OSP_MIN_MAXCONNECTIONS ((unsigned int)1)
-#define OSP_MAX_MAXCONNECTIONS ((unsigned int)1000)
-#define OSP_DEF_RETRYDELAY ((unsigned int)0)
-#define OSP_MIN_RETRYDELAY ((unsigned int)0)
-#define OSP_MAX_RETRYDELAY ((unsigned int)10)
-#define OSP_DEF_RETRYLIMIT ((unsigned int)2)
-#define OSP_MIN_RETRYLIMIT ((unsigned int)0)
-#define OSP_MAX_RETRYLIMIT ((unsigned int)100)
-#define OSP_DEF_TIMEOUT ((unsigned int)500)
-#define OSP_MIN_TIMEOUT ((unsigned int)200)
-#define OSP_MAX_TIMEOUT ((unsigned int)10000)
-#define OSP_DEF_AUTHPOLICY ((enum osp_authpolicy)OSP_AUTH_YES)
-#define OSP_AUDIT_URL ((char*)"localhost")
-#define OSP_LOCAL_VALIDATION ((int)1)
-#define OSP_SSL_LIFETIME ((unsigned int)300)
-#define OSP_HTTP_PERSISTENCE ((int)1)
-#define OSP_CUSTOMER_ID ((char*)"")
-#define OSP_DEVICE_ID ((char*)"")
-#define OSP_DEF_DESTINATIONS ((unsigned int)5)
-
-struct osp_provider {
- char name[OSP_NORSTR_SIZE];
- char privatekey[OSP_NORSTR_SIZE];
- char localcert[OSP_NORSTR_SIZE];
- unsigned int cacount;
- char cacerts[OSP_MAX_CERTS][OSP_NORSTR_SIZE];
- unsigned int spcount;
- char srvpoints[OSP_MAX_SRVS][OSP_NORSTR_SIZE];
- int maxconnections;
- int retrydelay;
- int retrylimit;
- int timeout;
- char source[OSP_NORSTR_SIZE];
- enum osp_authpolicy authpolicy;
- OSPTPROVHANDLE handle;
- struct osp_provider *next;
-};
-
-AST_MUTEX_DEFINE_STATIC(osplock);
-static unsigned int osp_usecount = 0;
-static int osp_initialized = 0;
-static int osp_hardware = 0;
-static struct osp_provider* ospproviders = NULL;
-static unsigned int osp_tokenformat = TOKEN_ALGO_SIGNED;
-
-static int osp_buildProvider(
- struct ast_config* cfg, /* OSP configuration */
- char* provider); /* OSP provider context name */
-static int osp_getPolicy(
- const char* provider, /* OSP provider context name */
- int* policy); /* OSP authentication policy, output */
-static int osp_genTransaction(
- const char* provider, /* OSP provider context name */
- int* transaction, /* OSP transaction handle, output */
- unsigned int sourcesize, /* Size of source buffer, in/output */
- char* source); /* Source of provider context, output */
-static int osp_valToken(
- int transaction, /* OSP transaction handle */
- const char* source, /* Source of in_bound call */
- const char* dest, /* Destination of in_bound call */
- const char* calling, /* Calling number */
- const char* called, /* Called number */
- const char* token, /* OSP token, may be empty */
- unsigned int* timelimit); /* Call duration limit, output */
-static unsigned int osp_choTimelimit(
- unsigned int in, /* In_bound OSP timelimit */
- unsigned int out); /* Out_bound OSP timelimit */
-static enum OSPEFAILREASON reason2cause(
- int reason); /* Last call failure reason */
-static int osp_chkDest(
- const char* callednum, /* Called number */
- const char* callingnum, /* Calling number */
- char* destination, /* Destination IP in OSP format */
- unsigned int tokenlen, /* OSP token length */
- const char* token, /* OSP token */
- enum OSPEFAILREASON* cause, /* Failure cause, output */
- struct ast_osp_result* result); /* OSP lookup results, in/output */
-
-static int osp_load(void);
-static int osp_unload(void);
-static int osp_show(int fd, int argc, char *argv[]);
-
-static int osp_buildProvider(
- struct ast_config *cfg, /* OSP configuration */
- char* provider) /* OSP provider context name */
-{
- int res;
- unsigned int t, i, j;
- struct osp_provider* p;
- struct ast_variable* v;
- OSPTPRIVATEKEY privatekey;
- OSPTCERT localcert;
- const char* psrvpoints[OSP_MAX_SRVS];
- OSPTCERT cacerts[OSP_MAX_CERTS];
- const OSPTCERT* pcacerts[OSP_MAX_CERTS];
- int error = OSPC_ERR_NO_ERROR;
-
- p = ast_calloc(1, sizeof(*p));
- if (!p) {
- return(-1);
- }
-
- ast_copy_string(p->name, provider, sizeof(p->name));
- p->handle = OSP_INVALID_HANDLE;
- snprintf(p->privatekey, sizeof(p->privatekey), "%s/%s-privatekey.pem", ast_config_AST_KEY_DIR, provider);
- snprintf(p->localcert, sizeof(p->localcert), "%s/%s-localcert.pem", ast_config_AST_KEY_DIR, provider);
- p->maxconnections = OSP_DEF_MAXCONNECTIONS;
- p->retrydelay = OSP_DEF_RETRYDELAY;
- p->retrylimit = OSP_DEF_RETRYLIMIT;
- p->timeout = OSP_DEF_TIMEOUT;
- p->authpolicy = OSP_DEF_AUTHPOLICY;
-
- v = ast_variable_browse(cfg, provider);
- while(v) {
- if (!strcasecmp(v->name, "privatekey")) {
- if (v->value[0] == '/') {
- ast_copy_string(p->privatekey, v->value, sizeof(p->privatekey));
- } else {
- snprintf(p->privatekey, sizeof(p->privatekey), "%s/%s", ast_config_AST_KEY_DIR, v->value);
- }
- ast_log(LOG_DEBUG, "OSP: privatekey '%s'\n", p->privatekey);
- } else if (!strcasecmp(v->name, "localcert")) {
- if (v->value[0] == '/') {
- ast_copy_string(p->localcert, v->value, sizeof(p->localcert));
- } else {
- snprintf(p->localcert, sizeof(p->localcert), "%s/%s", ast_config_AST_KEY_DIR, v->value);
- }
- ast_log(LOG_DEBUG, "OSP: localcert '%s'\n", p->localcert);
- } else if (!strcasecmp(v->name, "cacert")) {
- if (p->cacount < OSP_MAX_CERTS) {
- if (v->value[0] == '/') {
- ast_copy_string(p->cacerts[p->cacount], v->value, sizeof(p->cacerts[0]));
- } else {
- snprintf(p->cacerts[p->cacount], sizeof(p->cacerts[0]), "%s/%s", ast_config_AST_KEY_DIR, v->value);
- }
- ast_log(LOG_DEBUG, "OSP: cacert[%d]: '%s'\n", p->cacount, p->cacerts[p->cacount]);
- p->cacount++;
- } else {
- ast_log(LOG_WARNING, "OSP: Too many CA Certificates at line %d\n", v->lineno);
- }
- } else if (!strcasecmp(v->name, "servicepoint")) {
- if (p->spcount < OSP_MAX_SRVS) {
- ast_copy_string(p->srvpoints[p->spcount], v->value, sizeof(p->srvpoints[0]));
- ast_log(LOG_DEBUG, "OSP: servicepoint[%d]: '%s'\n", p->spcount, p->srvpoints[p->spcount]);
- p->spcount++;
- } else {
- ast_log(LOG_WARNING, "OSP: Too many Service Points at line %d\n", v->lineno);
- }
- } else if (!strcasecmp(v->name, "maxconnections")) {
- if ((sscanf(v->value, "%d", &t) == 1) && (t >= OSP_MIN_MAXCONNECTIONS) && (t <= OSP_MAX_MAXCONNECTIONS)) {
- p->maxconnections = t;
- ast_log(LOG_DEBUG, "OSP: maxconnections '%d'\n", t);
- } else {
- ast_log(LOG_WARNING, "OSP: maxconnections should be an integer from %d to %d, not '%s' at line %d\n",
- OSP_MIN_MAXCONNECTIONS, OSP_MAX_MAXCONNECTIONS, v->value, v->lineno);
- }
- } else if (!strcasecmp(v->name, "retrydelay")) {
- if ((sscanf(v->value, "%d", &t) == 1) && (t >= OSP_MIN_RETRYDELAY) && (t <= OSP_MAX_RETRYDELAY)) {
- p->retrydelay = t;
- ast_log(LOG_DEBUG, "OSP: retrydelay '%d'\n", t);
- } else {
- ast_log(LOG_WARNING, "OSP: retrydelay should be an integer from %d to %d, not '%s' at line %d\n",
- OSP_MIN_RETRYDELAY, OSP_MAX_RETRYDELAY, v->value, v->lineno);
- }
- } else if (!strcasecmp(v->name, "retrylimit")) {
- if ((sscanf(v->value, "%d", &t) == 1) && (t >= OSP_MIN_RETRYLIMIT) && (t <= OSP_MAX_RETRYLIMIT)) {
- p->retrylimit = t;
- ast_log(LOG_DEBUG, "OSP: retrylimit '%d'\n", t);
- } else {
- ast_log(LOG_WARNING, "OSP: retrylimit should be an integer from %d to %d, not '%s' at line %d\n",
- OSP_MIN_RETRYLIMIT, OSP_MAX_RETRYLIMIT, v->value, v->lineno);
- }
- } else if (!strcasecmp(v->name, "timeout")) {
- if ((sscanf(v->value, "%d", &t) == 1) && (t >= OSP_MIN_TIMEOUT) && (t <= OSP_MAX_TIMEOUT)) {
- p->timeout = t;
- ast_log(LOG_DEBUG, "OSP: timeout '%d'\n", t);
- } else {
- ast_log(LOG_WARNING, "OSP: timeout should be an integer from %d to %d, not '%s' at line %d\n",
- OSP_MIN_TIMEOUT, OSP_MAX_TIMEOUT, v->value, v->lineno);
- }
- } else if (!strcasecmp(v->name, "source")) {
- ast_copy_string(p->source, v->value, sizeof(p->source));
- ast_log(LOG_DEBUG, "OSP: source '%s'\n", p->source);
- } else if (!strcasecmp(v->name, "authpolicy")) {
- if ((sscanf(v->value, "%d", &t) == 1) && ((t == OSP_AUTH_NO) || (t == OSP_AUTH_YES) || (t == OSP_AUTH_EXCLUSIVE))) {
- p->authpolicy = t;
- ast_log(LOG_DEBUG, "OSP: authpolicy '%d'\n", t);
- } else {
- ast_log(LOG_WARNING, "OSP: authpolicy should be %d, %d or %d, not '%s' at line %d\n",
- OSP_AUTH_NO, OSP_AUTH_YES, OSP_AUTH_EXCLUSIVE, v->value, v->lineno);
- }
- }
- v = v->next;
- }
-
- error = OSPPUtilLoadPEMPrivateKey(p->privatekey, &privatekey);
- if (error != OSPC_ERR_NO_ERROR) {
- ast_log(LOG_WARNING, "OSP: Unable to load privatekey '%s'\n", p->privatekey);
- free(p);
- return(-1);
- }
-
- error = OSPPUtilLoadPEMCert(p->localcert, &localcert);
- if (error != OSPC_ERR_NO_ERROR) {
- ast_log(LOG_WARNING, "OSP: Unable to load localcert '%s'\n", p->localcert);
- if (privatekey.PrivateKeyData) {
- free(privatekey.PrivateKeyData);
- }
- free(p);
- return(-1);
- }
-
- if (p->cacount < 1) {
- snprintf(p->cacerts[p->cacount], sizeof(p->cacerts[0]), "%s/%s-cacert.pem", ast_config_AST_KEY_DIR, provider);
- ast_log(LOG_DEBUG, "OSP: cacert[%d]: '%s'\n", p->cacount, p->cacerts[p->cacount]);
- p->cacount++;
- }
- for (i = 0; i < p->cacount; i++) {
- error = OSPPUtilLoadPEMCert(p->cacerts[i], &cacerts[i]);
- if (error != OSPC_ERR_NO_ERROR) {
- ast_log(LOG_WARNING, "OSP: Unable to load cacert '%s'\n", p->cacerts[i]);
- for (j = 0; j < i; j++) {
- if (cacerts[j].CertData) {
- free(cacerts[j].CertData);
- }
- }
- if (localcert.CertData) {
- free(localcert.CertData);
- }
- if (privatekey.PrivateKeyData) {
- free(privatekey.PrivateKeyData);
- }
- free(p);
- return(-1);
- }
- pcacerts[i] = &cacerts[i];
- }
-
- for (i = 0; i < p->spcount; i++) {
- psrvpoints[i] = p->srvpoints[i];
- }
-
- error = OSPPProviderNew(
- p->spcount, psrvpoints,
- NULL,
- OSP_AUDIT_URL,
- &privatekey,
- &localcert,
- p->cacount, pcacerts,
- OSP_LOCAL_VALIDATION,
- OSP_SSL_LIFETIME,
- p->maxconnections,
- OSP_HTTP_PERSISTENCE,
- p->retrydelay,
- p->retrylimit,
- p->timeout,
- OSP_CUSTOMER_ID,
- OSP_DEVICE_ID,
- &p->handle);
- if (error != OSPC_ERR_NO_ERROR) {
- ast_log(LOG_WARNING, "OSP: Unable to initialize provider '%s'\n", provider);
- free(p);
- res = -1;
- } else {
- ast_log(LOG_DEBUG, "OSP: provider '%s'\n", provider);
- ast_mutex_lock(&osplock);
- p->next = ospproviders;
- ospproviders = p;
- ast_mutex_unlock(&osplock);
- res = 0;
- }
-
- for (i = 0; i < p->cacount; i++) {
- if (cacerts[i].CertData) {
- free(cacerts[i].CertData);
- }
- }
- if (localcert.CertData) {
- free(localcert.CertData);
- }
- if (privatekey.PrivateKeyData) {
- free(privatekey.PrivateKeyData);
- }
-
- return(res);
-}
-
-static int osp_getPolicy(
- const char* provider, /* OSP provider context name */
- int* policy) /* OSP authentication policy, output */
-{
- int res = 0;
- struct osp_provider* p;
-
- ast_mutex_lock(&osplock);
- p = ospproviders;
- while(p) {
- if (!strcasecmp(p->name, provider)) {
- *policy = p->authpolicy;
- ast_log(LOG_DEBUG, "OSP: authpolicy '%d'\n", *policy);
- res = 1;
- break;
- }
- p = p->next;
- }
- ast_mutex_unlock(&osplock);
-
- return(res);
-}
-
-static int osp_genTransaction(
- const char* provider, /* OSP provider context name */
- int* transaction, /* OSP transaction handle, output */
- unsigned int sourcesize, /* Size of source buffer, in/output */
- char* source) /* Source of provider context, output */
-{
- int res = 0;
- struct osp_provider *p;
- int error;
-
- ast_mutex_lock(&osplock);
- p = ospproviders;
- while(p) {
- if (!strcasecmp(p->name, provider)) {
- error = OSPPTransactionNew(p->handle, transaction);
- if (error == OSPC_ERR_NO_ERROR) {
- ast_log(LOG_DEBUG, "OSP: transaction '%d'\n", *transaction);
- ast_copy_string(source, p->source, sourcesize);
- ast_log(LOG_DEBUG, "OSP: source '%s'\n", source);
- res = 1;
- } else {
- *transaction = OSP_INVALID_HANDLE;
- ast_log(LOG_WARNING, "OSP: Unable to create transaction handle\n");
- res = -1;
- }
- break;
- }
- p = p->next;
- }
- ast_mutex_unlock(&osplock);
-
- return(res);
-}
-
-static int osp_valToken(
- int transaction, /* OSP transaction handle */
- const char* source, /* Source of in_bound call */
- const char* dest, /* Destination of in_bound call */
- const char* calling, /* Calling number */
- const char* called, /* Called number */
- const char* token, /* OSP token, may be empty */
- unsigned int* timelimit) /* Call duration limit, output */
-{
- int res = 0;
- char tokenstr[OSP_TOKSTR_SIZE];
- int tokenlen;
- unsigned int authorised;
- unsigned int dummy = 0;
- int error;
-
- tokenlen = ast_base64decode(tokenstr, token, strlen(token));
- error = OSPPTransactionValidateAuthorisation(
- transaction,
- source, dest, NULL, NULL,
- calling ? calling : "", OSPC_E164,
- called, OSPC_E164,
- 0, NULL,
- tokenlen, tokenstr,
- &authorised,
- timelimit,
- &dummy, NULL,
- osp_tokenformat);
- if (error == OSPC_ERR_NO_ERROR) {
- if (authorised) {
- ast_log(LOG_DEBUG, "OSP: Authorised\n");
- res = 1;
- }
- }
- return(res);
-}
-
-int ast_osp_auth(
- const char* provider, /* OSP provider context name */
- int* transaction, /* OSP transaction handle, output */
- const char* source, /* Source of in_bound call */
- const char* calling, /* Calling number */
- const char* called, /* Called number */
- const char* token, /* OSP token, may be empty */
- unsigned int* timelimit) /* Call duration limit, output */
-{
- int res;
- char dest[OSP_NORSTR_SIZE];
- int policy = OSP_AUTH_YES;
-
- *transaction = OSP_INVALID_HANDLE;
- *timelimit = OSP_DEF_TIMELIMIT;
-
- res = osp_getPolicy(provider, &policy);
- if (!res) {
- ast_log(LOG_WARNING, "OSP: Unabe to find authentication policy\n");
- return(-1);
- }
-
- switch (policy) {
- case OSP_AUTH_NO:
- res = 1;
- break;
- case OSP_AUTH_EXCLUSIVE:
- if (ast_strlen_zero(token)) {
- res = 0;
- } else if ((res = osp_genTransaction(provider, transaction, sizeof(dest), dest)) <= 0) {
- *transaction = OSP_INVALID_HANDLE;
- ast_log(LOG_WARNING, "OSP: Unable to generate transaction handle\n");
- res = -1;
- } else {
- res = osp_valToken(*transaction, source, dest, calling, called, token, timelimit);
- }
- break;
- case OSP_AUTH_YES:
- default:
- if (ast_strlen_zero(token)) {
- res = 1;
- } else if ((res = osp_genTransaction(provider, transaction, sizeof(dest), dest)) <= 0) {
- *transaction = OSP_INVALID_HANDLE;
- ast_log(LOG_WARNING, "OSP: Unable to generate transaction handle\n");
- res = -1;
- } else {
- res = osp_valToken(*transaction, source, dest, calling, called, token, timelimit);
- }
- break;
- }
-
- if (!res) {
- OSPPTransactionRecordFailure(*transaction, OSPC_FAIL_CALL_REJECTED);
- }
-
- return(res);
-}
-
-static unsigned int osp_choTimelimit(
- unsigned int in, /* In_bound OSP timelimit */
- unsigned int out) /* Out_bound OSP timelimit */
-{
- if (in == OSP_DEF_TIMELIMIT) {
- return (out);
- } else if (out == OSP_DEF_TIMELIMIT) {
- return (in);
- } else {
- return(in < out ? in : out);
- }
-}
-
-static int osp_chkDest(
- const char* callednum, /* Called number */
- const char* callingnum, /* Calling number */
- char* destination, /* Destination IP in OSP format */
- unsigned int tokenlen, /* OSP token length */
- const char* token, /* OSP token */
- enum OSPEFAILREASON* cause, /* Failure cause, output */
- struct ast_osp_result* result) /* OSP lookup results, in/output */
-{
- int res = 0;
- OSPE_DEST_OSP_ENABLED enabled;
- OSPE_DEST_PROT protocol;
- int error;
-
- if (strlen(destination) <= 2) {
- *cause = OSPC_FAIL_INCOMPATIBLE_DEST;
- } else {
- error = OSPPTransactionIsDestOSPEnabled(result->outhandle, &enabled);
- if ((error == OSPC_ERR_NO_ERROR) && (enabled == OSPE_OSP_FALSE)) {
- result->token[0] = '\0';
- } else {
- ast_base64encode(result->token, token, tokenlen, sizeof(result->token) - 1);
- }
-
- error = OSPPTransactionGetDestProtocol(result->outhandle, &protocol);
- if (error != OSPC_ERR_NO_ERROR) {
- *cause = OSPC_FAIL_PROTOCOL_ERROR;
- } else {
- res = 1;
- /* Strip leading and trailing brackets */
- destination[strlen(destination) - 1] = '\0';
- switch(protocol) {
- case OSPE_DEST_PROT_H323_SETUP:
- ast_copy_string(result->tech, "H323", sizeof(result->tech));
- ast_log(LOG_DEBUG, "OSP: protocol '%d'\n", protocol);
- snprintf(result->dest, sizeof(result->dest), "%s@%s", callednum, destination + 1);
- ast_copy_string(result->calling, callingnum, sizeof(result->calling));
- break;
- case OSPE_DEST_PROT_SIP:
- ast_copy_string(result->tech, "SIP", sizeof(result->tech));
- ast_log(LOG_DEBUG, "OSP: protocol '%d'\n", protocol);
- snprintf(result->dest, sizeof(result->dest), "%s@%s", callednum, destination + 1);
- ast_copy_string(result->calling, callingnum, sizeof(result->calling));
- break;
- case OSPE_DEST_PROT_IAX:
- ast_copy_string(result->tech, "IAX", sizeof(result->tech));
- ast_log(LOG_DEBUG, "OSP: protocol '%d'\n", protocol);
- snprintf(result->dest, sizeof(result->dest), "%s@%s", callednum, destination + 1);
- ast_copy_string(result->calling, callingnum, sizeof(result->calling));
- break;
- default:
- ast_log(LOG_DEBUG, "OSP: Unknown protocol '%d'\n", protocol);
- *cause = OSPC_FAIL_PROTOCOL_ERROR;
- res = 0;
- }
- }
- }
- return(res);
-}
-
-int ast_osp_lookup(
- const char* provider, /* OSP provider conttext name */
- const char* srcdev, /* Source device of out_bound call */
- const char* calling, /* Calling number */
- const char* called, /* Called number */
- struct ast_osp_result* result) /* OSP lookup results, in/output */
-{
- int res;
- char source[OSP_NORSTR_SIZE];
- unsigned int callidlen;
- char callidstr[OSPC_CALLID_MAXSIZE];
- char callingnum[OSP_NORSTR_SIZE];
- char callednum[OSP_NORSTR_SIZE];
- char destination[OSP_NORSTR_SIZE];
- unsigned int tokenlen;
- char token[OSP_TOKSTR_SIZE];
- unsigned int dummy = 0;
- enum OSPEFAILREASON cause;
- int error;
-
- result->outhandle = OSP_INVALID_HANDLE;
- result->tech[0] = '\0';
- result->dest[0] = '\0';
- result->calling[0] = '\0';
- result->token[0] = '\0';
- result->numresults = 0;
- result->outtimelimit = OSP_DEF_TIMELIMIT;
-
- if ((res = osp_genTransaction(provider, &result->outhandle, sizeof(source), source)) <= 0) {
- result->outhandle = OSP_INVALID_HANDLE;
- if (result->inhandle != OSP_INVALID_HANDLE) {
- OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NO_ROUTE_TO_DEST);
- }
- ast_log(LOG_WARNING, "OSP: Unable to generate transaction handle\n");
- return(-1);
- }
-
- res = 0;
- dummy = 0;
- result->numresults = OSP_DEF_DESTINATIONS;
- error = OSPPTransactionRequestAuthorisation(
- result->outhandle,
- source, srcdev,
- calling ? calling : "", OSPC_E164,
- called, OSPC_E164,
- NULL,
- 0, NULL,
- NULL,
- &result->numresults,
- &dummy, NULL);
- if (error != OSPC_ERR_NO_ERROR) {
- result->numresults = 0;
- OSPPTransactionRecordFailure(result->outhandle, OSPC_FAIL_NORMAL_UNSPECIFIED);
- if (result->inhandle != OSP_INVALID_HANDLE) {
- OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NO_ROUTE_TO_DEST);
- }
- return(res);
- }
-
- if (!result->numresults) {
- result->numresults = 0;
- OSPPTransactionRecordFailure(result->outhandle, OSPC_FAIL_NO_ROUTE_TO_DEST);
- if (result->inhandle != OSP_INVALID_HANDLE) {
- OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NO_ROUTE_TO_DEST);
- }
- return(res);
- }
-
- callidlen = sizeof(callidstr);
- tokenlen = sizeof(token);
- error = OSPPTransactionGetFirstDestination(
- result->outhandle,
- 0, NULL, NULL,
- &result->outtimelimit,
- &callidlen, callidstr,
- sizeof(callednum), callednum,
- sizeof(callingnum), callingnum,
- sizeof(destination), destination,
- 0, NULL,
- &tokenlen, token);
- if (error != OSPC_ERR_NO_ERROR) {
- result->token[0] = '\0';
- result->numresults = 0;
- result->outtimelimit = OSP_DEF_TIMELIMIT;
- OSPPTransactionRecordFailure(result->outhandle, OSPC_FAIL_NORMAL_UNSPECIFIED);
- if (result->inhandle != OSP_INVALID_HANDLE) {
- OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NO_ROUTE_TO_DEST);
- }
- ast_log(LOG_DEBUG, "OSP: Unable to get first route\n");
- return(res);
- }
-
- do {
- result->outtimelimit = osp_choTimelimit(result->intimelimit, result->outtimelimit);
- ast_log(LOG_DEBUG, "OSP: outtimelimit '%d'\n", result->outtimelimit);
- ast_log(LOG_DEBUG, "OSP: called '%s'\n", callednum);
- ast_log(LOG_DEBUG, "OSP: calling '%s'\n", callingnum);
- ast_log(LOG_DEBUG, "OSP: destination '%s'\n", destination);
- ast_log(LOG_DEBUG, "OSP: token size '%d'\n", tokenlen);
-
- res = osp_chkDest(callednum, callingnum, destination, tokenlen, token, &cause, result);
- if (!res) {
- result->numresults--;
- if (result->numresults) {
- callidlen = sizeof(callidstr);
- tokenlen = sizeof(token);
- error = OSPPTransactionGetNextDestination(
- result->outhandle,
- cause,
- 0, NULL, NULL,
- &result->outtimelimit,
- &callidlen, callidstr,
- sizeof(callednum), callednum,
- sizeof(callingnum), callingnum,
- sizeof(destination), destination,
- 0, NULL,
- &tokenlen, token);
- if (error != OSPC_ERR_NO_ERROR) {
- result->token[0] = '\0';
- result->numresults = 0;
- result->outtimelimit = OSP_DEF_TIMELIMIT;
- OSPPTransactionRecordFailure(result->outhandle, OSPC_FAIL_NORMAL_UNSPECIFIED);
- if (result->inhandle != OSP_INVALID_HANDLE) {
- OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NO_ROUTE_TO_DEST);
- }
- break;
- }
- } else {
- result->token[0] = '\0';
- result->numresults = 0;
- result->outtimelimit = OSP_DEF_TIMELIMIT;
- OSPPTransactionRecordFailure(result->outhandle, cause);
- if (result->inhandle != OSP_INVALID_HANDLE) {
- OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NO_ROUTE_TO_DEST);
- }
- }
- } else {
- result->numresults--;
- }
- } while(!res && result->numresults);
-
- return(res);
-}
-
-static enum OSPEFAILREASON reason2cause(
- int reason) /* Last call failure reason */
-{
- enum OSPEFAILREASON cause;
-
- switch(reason) {
- case AST_CAUSE_NOTDEFINED:
- cause = OSPC_FAIL_NONE;
- break;
- case AST_CAUSE_BUSY:
- cause = OSPC_FAIL_USER_BUSY;
- break;
- case AST_CAUSE_CONGESTION:
- cause = OSPC_FAIL_SWITCHING_EQUIPMENT_CONGESTION;
- break;
- case AST_CAUSE_UNALLOCATED:
- cause = OSPC_FAIL_UNALLOC_NUMBER;
- break;
- case AST_CAUSE_NOANSWER:
- cause = OSPC_FAIL_NO_ANSWER_FROM_USER;
- break;
- case AST_CAUSE_NORMAL:
- default:
- cause = OSPC_FAIL_NORMAL_CALL_CLEARING;
- break;
- }
-
- return(cause);
-}
-
-int ast_osp_next(
- int reason, /* Last desintaion failure reason */
- struct ast_osp_result *result) /* OSP lookup results, output */
-{
- int res = 0;
- unsigned int callidlen;
- char callidstr[OSPC_CALLID_MAXSIZE];
- char callingnum[OSP_NORSTR_SIZE];
- char callednum[OSP_NORSTR_SIZE];
- char destination[OSP_NORSTR_SIZE];
- unsigned int tokenlen;
- char token[OSP_TOKSTR_SIZE];
- enum OSPEFAILREASON cause;
- int error;
-
- result->tech[0] = '\0';
- result->dest[0] = '\0';
- result->calling[0] = '\0';
- result->token[0] = '\0';
- result->outtimelimit = OSP_DEF_TIMELIMIT;
-
- if (result->outhandle == OSP_INVALID_HANDLE) {
- result->numresults = 0;
- if (result->inhandle != OSP_INVALID_HANDLE) {
- OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NO_ROUTE_TO_DEST);
- }
- ast_log(LOG_WARNING, "OSP: Transaction handle undefined\n");
- return(-1);
- }
-
- cause = reason2cause(reason);
- if (!result->numresults) {
- OSPPTransactionRecordFailure(result->outhandle, cause);
- if (result->inhandle != OSP_INVALID_HANDLE) {
- OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NO_ROUTE_TO_DEST);
- }
- ast_log(LOG_DEBUG, "OSP: No more destination\n");
- return(res);
- }
-
- while(!res && result->numresults) {
- result->numresults--;
- callidlen = sizeof(callidstr);
- tokenlen = sizeof(token);
- error = OSPPTransactionGetNextDestination(
- result->outhandle,
- cause,
- 0, NULL, NULL,
- &result->outtimelimit,
- &callidlen, callidstr,
- sizeof(callednum), callednum,
- sizeof(callingnum), callingnum,
- sizeof(destination), destination,
- 0, NULL,
- &tokenlen, token);
- if (error == OSPC_ERR_NO_ERROR) {
- result->outtimelimit = osp_choTimelimit(result->intimelimit, result->outtimelimit);
- ast_log(LOG_DEBUG, "OSP: outtimelimit '%d'\n", result->outtimelimit);
- ast_log(LOG_DEBUG, "OSP: called '%s'\n", callednum);
- ast_log(LOG_DEBUG, "OSP: calling '%s'\n", callingnum);
- ast_log(LOG_DEBUG, "OSP: destination '%s'\n", destination);
- ast_log(LOG_DEBUG, "OSP: token size '%d'\n", tokenlen);
-
- res = osp_chkDest(callednum, callingnum, destination, tokenlen, token, &cause, result);
- if (!res && !result->numresults) {
- OSPPTransactionRecordFailure(result->outhandle, cause);
- if (result->inhandle != OSP_INVALID_HANDLE) {
- OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NO_ROUTE_TO_DEST);
- }
- }
- } else {
- result->token[0] = '\0';
- result->numresults = 0;
- result->outtimelimit = OSP_DEF_TIMELIMIT;
- OSPPTransactionRecordFailure(result->outhandle, OSPC_FAIL_NORMAL_UNSPECIFIED);
- if (result->inhandle != OSP_INVALID_HANDLE) {
- OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NO_ROUTE_TO_DEST);
- }
- }
- }
-
- return(res);
-}
-
-int ast_osp_finish(
- int handle, /* OSP in/out_bound transaction handle */
- int reason, /* Last destination failure reason */
- time_t start, /* Call start time */
- time_t connect, /* Call connect time */
- time_t end) /* Call end time*/
-{
- int res = 1;
- unsigned int dummy = 0;
- enum OSPEFAILREASON cause;
- time_t alert = 0;
- unsigned isPddInfoPresent = 0;
- unsigned pdd = 0;
- unsigned releaseSource = 0;
- unsigned char *confId = "";
- int error;
-
- if (handle == OSP_INVALID_HANDLE) {
- return(res);
- }
-
- if ((cause = reason2cause(reason)) != OSPC_FAIL_NONE) {
- OSPPTransactionRecordFailure(handle, cause);
- }
- error = OSPPTransactionReportUsage(
- handle,
- difftime(end, connect), start, end, alert, connect,
- isPddInfoPresent, pdd,
- releaseSource,
- confId,
- 0, 0, 0, 0,
- &dummy, NULL);
- if (error == OSPC_ERR_NO_ERROR) {
- ast_log(LOG_DEBUG, "OSP: Usage reported\n");
- res = 1;
- } else {
- ast_log(LOG_DEBUG, "OSP: Unable to report usage, error = %d\n", error);
- res = 0;
- }
- OSPPTransactionDelete(handle);
-
- return(res);
-}
-
-void ast_osp_adduse(void)
-{
- osp_usecount++;
-}
-
-void ast_osp_deluse(void)
-{
- if (osp_usecount > 0) {
- osp_usecount--;
- }
-}
-
-static char osp_usage[] =
-"Usage: show osp\n"
-" Displays information on Open Settlement Protocol support\n";
-
-static struct ast_cli_entry osp_cli = {
- {"show", "osp", NULL},
- osp_show,
- "Displays OSP information",
- osp_usage
-};
-
-static int osp_load(void)
-{
- char* t;
- unsigned int v;
- struct ast_config* cfg;
- int error = OSPC_ERR_NO_ERROR;
-
- cfg = ast_config_load(OSP_CONFIG_FILE);
- if (cfg) {
- t = ast_variable_retrieve(cfg, OSP_GENERAL_CAT, "accelerate");
- if (t && ast_true(t)) {
- if ((error = OSPPInit(1)) != OSPC_ERR_NO_ERROR) {
- ast_log(LOG_WARNING, "OSP: Unable to enable hardware accelleration\n");
- OSPPInit(0);
- } else {
- osp_hardware = 1;
- }
- } else {
- OSPPInit(0);
- }
- ast_log(LOG_DEBUG, "OSP: osp_hardware '%d'\n", osp_hardware);
-
- t = ast_variable_retrieve(cfg, OSP_GENERAL_CAT, "tokenformat");
- if (t) {
- if ((sscanf(t, "%d", &v) == 1) &&
- ((v == TOKEN_ALGO_SIGNED) || (v == TOKEN_ALGO_UNSIGNED) || (v == TOKEN_ALGO_BOTH)))
- {
- osp_tokenformat = v;
- } else {
- ast_log(LOG_WARNING, "tokenformat should be an integer from %d, %d or %d, not '%s'\n",
- TOKEN_ALGO_SIGNED, TOKEN_ALGO_UNSIGNED, TOKEN_ALGO_BOTH, t);
- }
- }
- ast_log(LOG_DEBUG, "OSP: osp_tokenformat '%d'\n", osp_tokenformat);
-
- t = ast_category_browse(cfg, NULL);
- while(t) {
- if (strcasecmp(t, OSP_GENERAL_CAT)) {
- osp_buildProvider(cfg, t);
- }
- t = ast_category_browse(cfg, t);
- }
-
- osp_initialized = 1;
-
- ast_config_destroy(cfg);
- } else {
- ast_log(LOG_WARNING, "OSP: Unable to find configuration. OSP support disabled\n");
- }
- ast_log(LOG_DEBUG, "OSP: osp_initialized '%d'\n", osp_initialized);
-
- return(0);
-}
-
-static int osp_unload(void)
-{
- struct osp_provider* p;
- struct osp_provider* next;
-
- if (osp_initialized) {
- ast_mutex_lock(&osplock);
- p = ospproviders;
- while(p) {
- next = p->next;
- OSPPProviderDelete(p->handle, 0);
- free(p);
- p = next;
- }
- ospproviders = NULL;
- ast_mutex_unlock(&osplock);
-
- OSPPCleanup();
-
- osp_usecount = 0;
- osp_tokenformat = TOKEN_ALGO_SIGNED;
- osp_hardware = 0;
- osp_initialized = 0;
- }
- return(0);
-}
-
-static int osp_show(int fd, int argc, char *argv[])
-{
- int i;
- int found = 0;
- struct osp_provider* p;
- char* provider = NULL;
- char* tokenalgo;
-
- if ((argc < 2) || (argc > 3)) {
- return(RESULT_SHOWUSAGE);
- }
- if (argc > 2) {
- provider = argv[2];
- }
- if (!provider) {
- switch (osp_tokenformat) {
- case TOKEN_ALGO_BOTH:
- tokenalgo = "Both";
- break;
- case TOKEN_ALGO_UNSIGNED:
- tokenalgo = "Unsigned";
- break;
- case TOKEN_ALGO_SIGNED:
- default:
- tokenalgo = "Signed";
- break;
- }
- ast_cli(fd, "OSP: %s %s %s\n",
- osp_initialized ? "Initialized" : "Uninitialized", osp_hardware ? "Accelerated" : "Normal", tokenalgo);
- }
-
- ast_mutex_lock(&osplock);
- p = ospproviders;
- while(p) {
- if (!provider || !strcasecmp(p->name, provider)) {
- if (found) {
- ast_cli(fd, "\n");
- }
- ast_cli(fd, " == OSP Provider '%s' == \n", p->name);
- ast_cli(fd, "Local Private Key: %s\n", p->privatekey);
- ast_cli(fd, "Local Certificate: %s\n", p->localcert);
- for (i = 0; i < p->cacount; i++) {
- ast_cli(fd, "CA Certificate %d: %s\n", i + 1, p->cacerts[i]);
- }
- for (i = 0; i < p->spcount; i++) {
- ast_cli(fd, "Service Point %d: %s\n", i + 1, p->srvpoints[i]);
- }
- ast_cli(fd, "Max Connections: %d\n", p->maxconnections);
- ast_cli(fd, "Retry Delay: %d seconds\n", p->retrydelay);
- ast_cli(fd, "Retry Limit: %d\n", p->retrylimit);
- ast_cli(fd, "Timeout: %d milliseconds\n", p->timeout);
- ast_cli(fd, "Source: %s\n", strlen(p->source) ? p->source : "<unspecified>");
- ast_cli(fd, "Auth Policy %d\n", p->authpolicy);
- ast_cli(fd, "OSP Handle: %d\n", p->handle);
- found++;
- }
- p = p->next;
- }
- ast_mutex_unlock(&osplock);
-
- if (!found) {
- if (provider) {
- ast_cli(fd, "Unable to find OSP provider '%s'\n", provider);
- } else {
- ast_cli(fd, "No OSP providers configured\n");
- }
- }
- return(RESULT_SUCCESS);
-}
-
-static int load_module(void *mod)
-{
- osp_load();
- ast_cli_register(&osp_cli);
- return 0;
-}
-
-static int reload(void *mod)
-{
- ast_cli_unregister(&osp_cli);
- osp_unload();
- osp_load();
- ast_cli_register(&osp_cli);
- return 0;
-}
-
-static int unload_module(void *mod)
-{
- ast_cli_unregister(&osp_cli);
- osp_unload();
- return 0;
-}
-
-static const char *description(void)
-{
- return "Open Settlement Protocol Support";
-}
-
-#if 0
-/* XXX usecount handling still needs to be fixed.
- */
-int usecount(void)
-{
- return(osp_usecount);
-}
-#endif
-
-static const char *key(void)
-{
- return ASTERISK_GPL_KEY;
-}
-
-STD_MOD(MOD_0, reload, NULL, NULL)
-
-