Wed Oct 28 15:49:16 2009

Asterisk developer's documentation


res_osp.c File Reference

Provide Open Settlement Protocol capability. More...

#include <sys/types.h>
#include <osp.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.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/causes.h"
#include "asterisk/callerid.h"
#include "asterisk/pbx.h"

Include dependency graph for res_osp.c:

Go to the source code of this file.

Data Structures

struct  osp_provider

Defines

#define MAX_CERTS   10
#define MAX_SERVICEPOINTS   10
#define OSP_DEFAULT_MAX_CONNECTIONS   20
#define OSP_DEFAULT_RETRY_DELAY   0
#define OSP_DEFAULT_RETRY_LIMIT   2
#define OSP_DEFAULT_TIMEOUT   500
#define OSP_MAX   256

Functions

 AST_MUTEX_DEFINE_STATIC (osplock)
int ast_osp_lookup (struct ast_channel *chan, char *provider, char *extension, char *callerid, struct ast_osp_result *result)
int ast_osp_next (struct ast_osp_result *result, int cause)
int ast_osp_terminate (int handle, int cause, time_t start, time_t duration)
int ast_osp_validate (char *provider, char *token, int *handle, unsigned int *timelimit, char *callerid, struct in_addr addr, char *extension)
static enum OSPEFAILREASON cause2reason (int cause)
static int config_load (void)
char * description (void)
 Provides a description of the module.
char * key ()
 Returns the ASTERISK_GPL_KEY.
int load_module (void)
 Initialize the module.
static int loadPemCert (unsigned char *FileName, unsigned char *buffer, int *len)
static int loadPemPrivateKey (unsigned char *FileName, unsigned char *buffer, int *len)
static int osp_build (struct ast_config *cfg, char *cat)
int reload (void)
 Reload stuff.
static int show_osp (int fd, int argc, char *argv[])
int unload_module (void)
 Cleanup all module structures, sockets, etc.
int usecount (void)
 Provides a usecount.

Variables

static struct ast_cli_entry cli_show_osp
static int hardware = 0
static int initialized = 0
static struct osp_providerproviders
static char show_osp_usage []
static unsigned tokenformat = TOKEN_ALGO_SIGNED


Detailed Description

Provide Open Settlement Protocol capability.

Definition in file res_osp.c.


Define Documentation

#define MAX_CERTS   10

Definition at line 62 of file res_osp.c.

Referenced by osp_build().

#define MAX_SERVICEPOINTS   10

Definition at line 63 of file res_osp.c.

Referenced by osp_build().

#define OSP_DEFAULT_MAX_CONNECTIONS   20

Definition at line 66 of file res_osp.c.

Referenced by osp_build().

#define OSP_DEFAULT_RETRY_DELAY   0

Definition at line 67 of file res_osp.c.

Referenced by osp_build().

#define OSP_DEFAULT_RETRY_LIMIT   2

Definition at line 68 of file res_osp.c.

Referenced by osp_build().

#define OSP_DEFAULT_TIMEOUT   500

Definition at line 69 of file res_osp.c.

Referenced by osp_build().

#define OSP_MAX   256

Definition at line 64 of file res_osp.c.

Referenced by ast_osp_lookup(), and ast_osp_validate().


Function Documentation

AST_MUTEX_DEFINE_STATIC ( osplock   ) 

int ast_osp_lookup ( struct ast_channel chan,
char *  provider,
char *  extension,
char *  callerid,
struct ast_osp_result result 
)

Definition at line 517 of file res_osp.c.

References ast_autoservice_start(), ast_autoservice_stop(), ast_base64encode(), ast_callerid_parse(), ast_channel_cmpwhentohangup(), ast_channel_setwhentohangup(), ast_isphonenumber(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_shrink_phone_number(), ast_osp_result::dest, osp_provider::handle, ast_osp_result::handle, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, n, osp_provider::name, osp_provider::next, ast_osp_result::numresults, OSP_MAX, pbx_builtin_getvar_helper(), osp_provider::source, ast_osp_result::tech, and ast_osp_result::token.

Referenced by osplookup_exec().

00518 {
00519    int cres;
00520    int res = 0;
00521    int counts;
00522    int tokenlen;
00523    unsigned int dummy=0;
00524    unsigned int timelimit;
00525    unsigned int callidlen;
00526    char callidstr[OSPC_CALLID_MAXSIZE] = "";
00527    struct osp_provider *osp;
00528    char source[OSP_MAX] = ""; /* Same length as osp->source */
00529    char callednum[2048]="";
00530    char callingnum[2048]="";
00531    char destination[2048]="";
00532    char token[2000];
00533    char tmp[256]="", *l, *n;
00534    OSPE_DEST_PROT prot;
00535    OSPE_DEST_OSP_ENABLED ospenabled;
00536    char *devinfo = NULL;
00537 
00538    result->handle = -1;
00539    result->numresults = 0;
00540    result->tech[0] = '\0';
00541    result->dest[0] = '\0';
00542    result->token[0] = '\0';
00543 
00544    if (!provider || !strlen(provider))
00545       provider = "default";
00546 
00547    if (!callerid)
00548       callerid = "";
00549    ast_copy_string(tmp, callerid, sizeof(tmp));
00550    ast_callerid_parse(tmp, &n, &l);
00551    if (!l)
00552       l = "";
00553    else {
00554       ast_shrink_phone_number(l);
00555       if (!ast_isphonenumber(l))
00556          l = "";
00557    }
00558    callerid = l;
00559 
00560    if (chan) {
00561       cres = ast_autoservice_start(chan);
00562       if (cres < 0)
00563          return cres;
00564    }
00565    ast_mutex_lock(&osplock);
00566    osp = providers;
00567    while(osp) {
00568       if (!strcasecmp(osp->name, provider)) {
00569          if (OSPPTransactionNew(osp->handle, &result->handle)) {
00570             ast_log(LOG_WARNING, "Unable to create OSP Transaction handle!\n");
00571          } else {
00572             ast_copy_string(source, osp->source, sizeof(source));
00573             res = 1;
00574          }
00575          break;
00576       }
00577       osp = osp->next;
00578    }
00579    ast_mutex_unlock(&osplock);
00580    if (res) {
00581       res = 0;
00582       /* No more than 10 back */
00583       counts = 10;
00584       dummy = 0;
00585       devinfo = pbx_builtin_getvar_helper (chan, "OSPPEER");
00586       if (!devinfo) {
00587          devinfo = "";
00588       }
00589       if (!OSPPTransactionRequestAuthorisation(result->handle, source, devinfo, 
00590            callerid,OSPC_E164, extension, OSPC_E164, NULL, 0, NULL, NULL, &counts, &dummy, NULL)) {
00591          if (counts) {
00592             tokenlen = sizeof(token);
00593             result->numresults = counts - 1;
00594             callidlen = sizeof(callidstr);
00595             if (!OSPPTransactionGetFirstDestination(result->handle, 0, NULL, NULL, &timelimit, &callidlen, callidstr, 
00596                sizeof(callednum), callednum, sizeof(callingnum), callingnum, sizeof(destination), destination, 0, NULL, &tokenlen, token)) {
00597                ast_log(LOG_DEBUG, "Got destination '%s' and called: '%s' calling: '%s' for '%s' (provider '%s')\n",
00598                   destination, callednum, callingnum, extension, provider);
00599                /* Only support OSP server with only one duration limit */
00600                if (ast_channel_cmpwhentohangup (chan, timelimit) < 0) {
00601                   ast_channel_setwhentohangup (chan, timelimit);  
00602                }
00603                do {
00604                   if (!OSPPTransactionIsDestOSPEnabled (result->handle, &ospenabled) && (ospenabled == OSPE_OSP_FALSE)) {
00605                      result->token[0] = 0;
00606                   }
00607                   else {
00608                      ast_base64encode(result->token, token, tokenlen, sizeof(result->token) - 1);
00609                   }
00610                   if ((strlen(destination) > 2) && !OSPPTransactionGetDestProtocol(result->handle, &prot)) {
00611                      res = 1;
00612                      /* Strip leading and trailing brackets */
00613                      destination[strlen(destination) - 1] = '\0';
00614                      switch(prot) {
00615                      case OSPE_DEST_PROT_H323_SETUP:
00616                         ast_copy_string(result->tech, "H323", sizeof(result->tech));
00617                         snprintf(result->dest, sizeof(result->dest), "%s@%s", callednum, destination + 1);
00618                         break;
00619                      case OSPE_DEST_PROT_SIP:
00620                         ast_copy_string(result->tech, "SIP", sizeof(result->tech));
00621                         snprintf(result->dest, sizeof(result->dest), "%s@%s", callednum, destination + 1);
00622                         break;
00623                      case OSPE_DEST_PROT_IAX:
00624                         ast_copy_string(result->tech, "IAX", sizeof(result->tech));
00625                         snprintf(result->dest, sizeof(result->dest), "%s@%s", callednum, destination + 1);
00626                         break;
00627                      default:
00628                         ast_log(LOG_DEBUG, "Unknown destination protocol '%d', skipping...\n", prot);
00629                         res = 0;
00630                      }
00631                      if (!res && result->numresults) {
00632                         result->numresults--;
00633                         callidlen = sizeof(callidstr);
00634                         if (OSPPTransactionGetNextDestination(result->handle, OSPC_FAIL_INCOMPATIBLE_DEST, 0, NULL, NULL, &timelimit, &callidlen, callidstr, 
00635                               sizeof(callednum), callednum, sizeof(callingnum), callingnum, sizeof(destination), destination, 0, NULL, &tokenlen, token)) {
00636                               break;
00637                         }
00638                      }
00639                   } else {
00640                      ast_log(LOG_DEBUG, "Missing destination protocol\n");
00641                      break;
00642                   }
00643                } while(!res && result->numresults);
00644             }
00645          }
00646          
00647       }
00648       if (!res) {
00649          OSPPTransactionDelete(result->handle);
00650          result->handle = -1;
00651       }
00652       
00653    }
00654    if (!osp) 
00655       ast_log(LOG_NOTICE, "OSP Provider '%s' does not exist!\n", provider);
00656    if (chan) {
00657       cres = ast_autoservice_stop(chan);
00658       if (cres < 0)
00659          return cres;
00660    }
00661    return res;
00662 }

int ast_osp_next ( struct ast_osp_result result,
int  cause 
)

Definition at line 664 of file res_osp.c.

References ast_base64encode(), ast_log(), ast_osp_result::dest, ast_osp_result::handle, LOG_DEBUG, ast_osp_result::numresults, ast_osp_result::tech, and ast_osp_result::token.

Referenced by ospnext_exec().

00665 {
00666    int res = 0;
00667    int tokenlen;
00668    unsigned int dummy=0;
00669    unsigned int timelimit;
00670    unsigned int callidlen;
00671    char callidstr[OSPC_CALLID_MAXSIZE] = "";
00672    char callednum[2048]="";
00673    char callingnum[2048]="";
00674    char destination[2048]="";
00675    char token[2000];
00676    OSPE_DEST_PROT prot;
00677    OSPE_DEST_OSP_ENABLED ospenabled;
00678 
00679    result->tech[0] = '\0';
00680    result->dest[0] = '\0';
00681    result->token[0] = '\0';
00682 
00683    if (result->handle > -1) {
00684       dummy = 0;
00685       if (result->numresults) {
00686          tokenlen = sizeof(token);
00687          while(!res && result->numresults) {
00688             result->numresults--;
00689             callidlen = sizeof(callidstr);
00690             if (!OSPPTransactionGetNextDestination(result->handle, OSPC_FAIL_INCOMPATIBLE_DEST, 0, NULL, NULL, &timelimit, &callidlen, callidstr, 
00691                            sizeof(callednum), callednum, sizeof(callingnum), callingnum, sizeof(destination), destination, 0, NULL, &tokenlen, token)) {
00692                if (!OSPPTransactionIsDestOSPEnabled (result->handle, &ospenabled) && (ospenabled == OSPE_OSP_FALSE)) {
00693                   result->token[0] = 0;
00694                }
00695                else {
00696                   ast_base64encode(result->token, token, tokenlen, sizeof(result->token) - 1);
00697                }
00698                if ((strlen(destination) > 2) && !OSPPTransactionGetDestProtocol(result->handle, &prot)) {
00699                   res = 1;
00700                   /* Strip leading and trailing brackets */
00701                   destination[strlen(destination) - 1] = '\0';
00702                   switch(prot) {
00703                   case OSPE_DEST_PROT_H323_SETUP:
00704                      ast_copy_string(result->tech, "H323", sizeof(result->tech));
00705                      snprintf(result->dest, sizeof(result->dest), "%s@%s", callednum, destination + 1);
00706                      break;
00707                   case OSPE_DEST_PROT_SIP:
00708                      ast_copy_string(result->tech, "SIP", sizeof(result->tech));
00709                      snprintf(result->dest, sizeof(result->dest), "%s@%s", callednum, destination + 1);
00710                      break;
00711                   case OSPE_DEST_PROT_IAX:
00712                      ast_copy_string(result->tech, "IAX", sizeof(result->tech));
00713                      snprintf(result->dest, sizeof(result->dest), "%s@%s", callednum, destination + 1);
00714                      break;
00715                   default:
00716                      ast_log(LOG_DEBUG, "Unknown destination protocol '%d', skipping...\n", prot);
00717                      res = 0;
00718                   }
00719                } else {
00720                   ast_log(LOG_DEBUG, "Missing destination protocol\n");
00721                   break;
00722                }
00723             }
00724          }
00725          
00726       }
00727       if (!res) {
00728          OSPPTransactionDelete(result->handle);
00729          result->handle = -1;
00730       }
00731       
00732    }
00733    return res;
00734 }

int ast_osp_terminate ( int  handle,
int  cause,
time_t  start,
time_t  duration 
)

Definition at line 755 of file res_osp.c.

References ast_log(), cause2reason(), LOG_DEBUG, and LOG_WARNING.

Referenced by ospfinished_exec(), and sip_hangup().

00756 {
00757    unsigned int dummy = 0;
00758    int res = -1;
00759    enum OSPEFAILREASON reason;
00760 
00761    time_t endTime = 0;
00762    time_t alertTime = 0;
00763    time_t connectTime = 0;
00764    unsigned isPddInfoPresent = 0;
00765    unsigned pdd = 0;
00766    unsigned releaseSource = 0;
00767    unsigned char *confId = "";
00768    
00769    reason = cause2reason(cause);
00770    if (OSPPTransactionRecordFailure(handle, reason))
00771       ast_log(LOG_WARNING, "Failed to record call termination for handle %d\n", handle);
00772    else if (OSPPTransactionReportUsage(handle, duration, start,
00773                 endTime,alertTime,connectTime,isPddInfoPresent,pdd,releaseSource,confId,
00774                       0, 0, 0, 0, &dummy, NULL))
00775       ast_log(LOG_WARNING, "Failed to report duration for handle %d\n", handle);
00776    else {
00777       ast_log(LOG_DEBUG, "Completed recording handle %d\n", handle);
00778       OSPPTransactionDelete(handle);
00779       res = 0;
00780    }
00781    return res;
00782 }

int ast_osp_validate ( char *  provider,
char *  token,
int *  handle,
unsigned int *  timelimit,
char *  callerid,
struct in_addr  addr,
char *  extension 
)

Definition at line 456 of file res_osp.c.

References ast_base64decode(), ast_callerid_parse(), ast_inet_ntoa(), ast_isphonenumber(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_shrink_phone_number(), ast_strdupa, osp_provider::handle, LOG_DEBUG, LOG_WARNING, n, osp_provider::name, osp_provider::next, OSP_MAX, and osp_provider::source.

00457 {
00458    char tmp[256]="", *l, *n;
00459    char iabuf[INET_ADDRSTRLEN];
00460    char source[OSP_MAX] = ""; /* Same length as osp->source */
00461    char *token2;
00462    int tokenlen;
00463    struct osp_provider *osp;
00464    int res = 0;
00465    unsigned int authorised, dummy;
00466 
00467    if (!provider || !strlen(provider))
00468       provider = "default";
00469 
00470    token2 = ast_strdupa(token);
00471    if (!token2)
00472       return -1;
00473    tokenlen = ast_base64decode(token2, token, strlen(token));
00474    *handle = -1;
00475    if (!callerid)
00476       callerid = "";
00477    ast_copy_string(tmp, callerid, sizeof(tmp));
00478    ast_callerid_parse(tmp, &n, &l);
00479    if (!l)
00480       l = "";
00481    else {
00482       ast_shrink_phone_number(l);
00483       if (!ast_isphonenumber(l))
00484          l = "";
00485    }
00486    callerid = l;
00487    ast_mutex_lock(&osplock);
00488    ast_inet_ntoa(iabuf, sizeof(iabuf), addr);
00489    osp = providers;
00490    while(osp) {
00491       if (!strcasecmp(osp->name, provider)) {
00492          if (OSPPTransactionNew(osp->handle, handle)) {
00493             ast_log(LOG_WARNING, "Unable to create OSP Transaction handle!\n");
00494          } else {
00495             ast_copy_string(source, osp->source, sizeof(source));
00496             res = 1;
00497          }
00498          break;
00499       }
00500       osp = osp->next;
00501    }
00502    ast_mutex_unlock(&osplock);
00503    if (res) {
00504       res = 0;
00505       dummy = 0;
00506       if (!OSPPTransactionValidateAuthorisation(*handle, iabuf, source, NULL, NULL, 
00507          callerid, OSPC_E164, extension, OSPC_E164, 0, "", tokenlen, token2, &authorised, timelimit, &dummy, NULL, tokenformat)) {
00508          if (authorised) {
00509             ast_log(LOG_DEBUG, "Validated token for '%s' from '%s@%s'\n", extension, callerid, iabuf);
00510             res = 1;
00511          }
00512       }
00513    }
00514    return res; 
00515 }

static enum OSPEFAILREASON cause2reason ( int  cause  )  [static]

Definition at line 736 of file res_osp.c.

References AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, AST_CAUSE_NOANSWER, AST_CAUSE_NORMAL, AST_CAUSE_NOTDEFINED, and AST_CAUSE_UNALLOCATED.

Referenced by ast_osp_terminate().

00737 {
00738    switch(cause) {
00739    case AST_CAUSE_BUSY:
00740       return OSPC_FAIL_USER_BUSY;
00741    case AST_CAUSE_CONGESTION:
00742       return OSPC_FAIL_SWITCHING_EQUIPMENT_CONGESTION;
00743    case AST_CAUSE_UNALLOCATED:
00744       return OSPC_FAIL_UNALLOC_NUMBER;
00745    case AST_CAUSE_NOTDEFINED:
00746       return OSPC_FAIL_NORMAL_UNSPECIFIED;
00747    case AST_CAUSE_NOANSWER:
00748       return OSPC_FAIL_NO_ANSWER_FROM_USER;
00749    case AST_CAUSE_NORMAL:
00750    default:
00751       return OSPC_FAIL_NORMAL_CALL_CLEARING;
00752    }
00753 }

static int config_load ( void   )  [static]

Definition at line 784 of file res_osp.c.

References ast_category_browse(), ast_config_destroy(), ast_config_load(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_true(), ast_variable_retrieve(), cfg, osp_provider::dead, free, LOG_NOTICE, LOG_WARNING, osp_provider::next, and osp_build().

Referenced by load_module(), and reload().

00785 {
00786    struct ast_config *cfg;
00787    char *cat;
00788    struct osp_provider *osp, *prev = NULL, *next;
00789    ast_mutex_lock(&osplock);
00790    osp = providers;
00791    while(osp) {
00792       osp->dead = 1;
00793       osp = osp->next;
00794    }
00795    ast_mutex_unlock(&osplock);
00796    cfg = ast_config_load("osp.conf");
00797    if (cfg) {
00798       if (!initialized) {
00799          cat = ast_variable_retrieve(cfg, "general", "accelerate");
00800          if (cat && ast_true(cat))
00801             if (OSPPInit(1)) {
00802                ast_log(LOG_WARNING, "Failed to enable hardware accelleration, falling back to software mode\n");
00803                OSPPInit(0);
00804             } else
00805                hardware = 1;
00806          else
00807             OSPPInit(0);
00808          initialized = 1;
00809       }
00810       cat = ast_variable_retrieve(cfg, "general", "tokenformat");
00811       if (cat) {
00812          if ((sscanf(cat, "%30d", &tokenformat) != 1) || (tokenformat < TOKEN_ALGO_SIGNED) || (tokenformat > TOKEN_ALGO_BOTH)) {
00813             tokenformat = TOKEN_ALGO_SIGNED;
00814             ast_log(LOG_WARNING, "tokenformat should be an integer from 0 to 2, not '%s'\n", cat);
00815          }
00816       }
00817       cat = ast_category_browse(cfg, NULL);
00818       while(cat) {
00819          if (strcasecmp(cat, "general"))
00820             osp_build(cfg, cat);
00821          cat = ast_category_browse(cfg, cat);
00822       }
00823       ast_config_destroy(cfg);
00824    } else
00825       ast_log(LOG_NOTICE, "No OSP configuration found.  OSP support disabled\n");
00826    ast_mutex_lock(&osplock);
00827    osp = providers;
00828    while(osp) {
00829       next = osp->next;
00830       if (osp->dead) {
00831          if (prev)
00832             prev->next = next;
00833          else
00834             providers = next;
00835          /* XXX Cleanup OSP structure first XXX */
00836          free(osp);
00837       } else 
00838          prev = osp;
00839       osp = next;
00840    }
00841    ast_mutex_unlock(&osplock);
00842    return 0;
00843 }

char* description ( void   ) 

Provides a description of the module.

Returns:
a short description of your module

Definition at line 872 of file res_osp.c.

00873 {
00874    return "Open Settlement Protocol Support";
00875 }

char* key ( void   ) 

Returns the ASTERISK_GPL_KEY.

This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:

 char *key(void) {
         return ASTERISK_GPL_KEY;
 }

Returns:
ASTERISK_GPL_KEY

Definition at line 883 of file res_osp.c.

References ASTERISK_GPL_KEY.

Referenced by __ast_key_get(), __load_resource(), ast_db_del(), ast_db_deltree(), ast_db_get(), ast_db_gettree(), ast_db_put(), ast_privacy_check(), ast_privacy_set(), authenticate(), authenticate_verify(), cache_lookup(), check_access(), check_key(), create_addr(), crypto_load(), database_show(), database_showkey(), del_exec(), function_db_exists(), function_db_read(), function_db_write(), get_exec(), init_keys(), manager_dbget(), manager_dbput(), misdn_set_opt_exec(), put_exec(), pw_cb(), register_verify(), reply_digest(), show_keys(), showkeys(), sort_internal(), try_load_key(), and update_key().

00884 {
00885    return ASTERISK_GPL_KEY;
00886 }

int load_module ( void   ) 

Initialize the module.

This function is called at module load time. Put all code in here that needs to set up your module's hardware, software, registrations, etc.

Returns:
This function should return 0 on success and non-zero on failure. If the module is not loaded successfully, Asterisk will call its unload_module() function.
Initialize the Agents module. This function is being called by Asterisk when loading the module. Among other thing it registers applications, cli commands and reads the cofiguration file.

Returns:
int Always 0.
TE STUFF END

Definition at line 859 of file res_osp.c.

References ast_cli_register(), and config_load().

00860 {
00861    config_load();
00862    ast_cli_register(&cli_show_osp);
00863    return 0;
00864 }

static int loadPemCert ( unsigned char *  FileName,
unsigned char *  buffer,
int *  len 
) [static]

Definition at line 353 of file res_osp.c.

References ast_log(), and LOG_WARNING.

Referenced by osp_build().

00354 {
00355     int length = 0;
00356     unsigned char *temp;
00357     BIO *bioIn = NULL;
00358     X509 *cert=NULL;
00359     int retVal = OSPC_ERR_NO_ERROR;
00360 
00361     temp = buffer;
00362     bioIn = BIO_new_file((const char*)FileName,"r");
00363     if (bioIn == NULL)
00364     {
00365       ast_log(LOG_WARNING,"Failed to find the File - %s \n",FileName);
00366       return -1;
00367     }
00368     else
00369     {
00370         cert = PEM_read_bio_X509(bioIn,NULL,NULL,NULL);
00371         if (cert == NULL)
00372         {
00373          ast_log(LOG_WARNING,"Failed to parse the Certificate from the File - %s \n",FileName);
00374          return -1;
00375         }
00376         else
00377         {
00378             length = i2d_X509(cert,&temp);
00379             if (cert == 0)
00380             {
00381             ast_log(LOG_WARNING,"Failed to parse the Certificate from the File - %s, Length=0 \n",FileName);
00382             return -1;
00383             }
00384             else
00385          {
00386                *len = length;
00387             }
00388         }
00389     }
00390 
00391     if (bioIn != NULL)
00392     {
00393         BIO_free(bioIn);
00394     }
00395 
00396     if (cert != NULL)
00397     {
00398         X509_free(cert);
00399     }
00400     return retVal;
00401 }

static int loadPemPrivateKey ( unsigned char *  FileName,
unsigned char *  buffer,
int *  len 
) [static]

Definition at line 406 of file res_osp.c.

References ast_log(), and LOG_WARNING.

Referenced by osp_build().

00407 {
00408     int length = 0;
00409     unsigned char *temp;
00410     BIO *bioIn = NULL;
00411     RSA *pKey = NULL;
00412     int retVal = OSPC_ERR_NO_ERROR;
00413 
00414     temp = buffer;
00415 
00416     bioIn = BIO_new_file((const char*)FileName,"r");
00417     if (bioIn == NULL)
00418     {
00419       ast_log(LOG_WARNING,"Failed to find the File - %s \n",FileName);
00420       return -1;
00421     }
00422     else
00423     {
00424         pKey = PEM_read_bio_RSAPrivateKey(bioIn,NULL,NULL,NULL);
00425         if (pKey == NULL)
00426         {
00427          ast_log(LOG_WARNING,"Failed to parse the Private Key from the File - %s \n",FileName);
00428          return -1;
00429         }
00430         else
00431         {
00432             length = i2d_RSAPrivateKey(pKey,&temp);
00433             if (length == 0)
00434             {
00435             ast_log(LOG_WARNING,"Failed to parse the Private Key from the File - %s, Length=0 \n",FileName);
00436             return -1;
00437             }
00438             else
00439             {
00440                 *len = length;
00441             }
00442         }
00443     }
00444     if (bioIn != NULL)
00445     {
00446         BIO_free(bioIn);
00447     }
00448 
00449     if (pKey != NULL)
00450     {
00451        RSA_free(pKey);
00452     }
00453     return retVal;
00454 }

static int osp_build ( struct ast_config cfg,
char *  cat 
) [static]

Definition at line 99 of file res_osp.c.

References ast_config_AST_KEY_DIR, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_variable_browse(), osp_provider::cacerts, osp_provider::cacount, osp_provider::dead, osp_provider::handle, ast_variable::lineno, loadPemCert(), loadPemPrivateKey(), osp_provider::localcert, osp_provider::localpvtkey, LOG_DEBUG, LOG_WARNING, malloc, MAX_CERTS, MAX_SERVICEPOINTS, osp_provider::maxconnections, ast_variable::name, osp_provider::name, ast_variable::next, osp_provider::next, OSP_DEFAULT_MAX_CONNECTIONS, OSP_DEFAULT_RETRY_DELAY, OSP_DEFAULT_RETRY_LIMIT, OSP_DEFAULT_TIMEOUT, osp_provider::retrydelay, osp_provider::retrylimit, osp_provider::servicepoints, osp_provider::source, osp_provider::spcount, osp_provider::timeout, and ast_variable::value.

Referenced by config_load().

00100 {
00101    OSPTCERT TheAuthCert[MAX_CERTS];
00102    unsigned char Reqbuf[4096],LocalBuf[4096],AuthBuf[MAX_CERTS][4096];
00103    struct ast_variable *v;
00104    struct osp_provider *osp;
00105    int x,length,errorcode=0;
00106    int mallocd=0,i;
00107    char *cacerts[MAX_CERTS];
00108    const char *servicepoints[MAX_SERVICEPOINTS];
00109    OSPTPRIVATEKEY privatekey;
00110    OSPTCERT localcert;
00111    OSPTCERT *authCerts[MAX_CERTS];
00112 
00113    
00114    
00115    ast_mutex_lock(&osplock);
00116    osp = providers;
00117    while(osp) {
00118       if (!strcasecmp(osp->name, cat))
00119          break;
00120       osp = osp->next;
00121    }
00122    ast_mutex_unlock(&osplock);
00123    if (!osp) {
00124       mallocd = 1;
00125       osp = malloc(sizeof(struct osp_provider));
00126       if (!osp) {
00127          ast_log(LOG_WARNING, "Out of memory!\n");
00128          return -1;
00129       }
00130       memset(osp, 0, sizeof(struct osp_provider));
00131       osp->handle = -1;
00132    }
00133    ast_copy_string(osp->name, cat, sizeof(osp->name));
00134    snprintf(osp->localpvtkey, sizeof(osp->localpvtkey) ,"%s/%s-privatekey.pem", ast_config_AST_KEY_DIR, cat);
00135    snprintf(osp->localcert, sizeof(osp->localpvtkey), "%s/%s-localcert.pem", ast_config_AST_KEY_DIR, cat);
00136    osp->maxconnections=OSP_DEFAULT_MAX_CONNECTIONS;
00137    osp->retrydelay = OSP_DEFAULT_RETRY_DELAY;
00138    osp->retrylimit = OSP_DEFAULT_RETRY_LIMIT;
00139    osp->timeout = OSP_DEFAULT_TIMEOUT;
00140    osp->source[0] = '\0';
00141    ast_log(LOG_DEBUG, "Building OSP Provider '%s'\n", cat);
00142    v = ast_variable_browse(cfg, cat);
00143    while(v) {
00144       if (!strcasecmp(v->name, "privatekey")) {
00145          if (v->value[0] == '/')
00146             ast_copy_string(osp->localpvtkey, v->value, sizeof(osp->localpvtkey));
00147          else
00148             snprintf(osp->localpvtkey, sizeof(osp->localpvtkey), "%s/%s", ast_config_AST_KEY_DIR , v->value);
00149       } else if (!strcasecmp(v->name, "localcert")) {
00150          if (v->value[0] == '/')
00151             ast_copy_string(osp->localcert, v->value, sizeof(osp->localcert));
00152          else
00153             snprintf(osp->localcert, sizeof(osp->localcert), "%s/%s", ast_config_AST_KEY_DIR, v->value);
00154       } else if (!strcasecmp(v->name, "cacert")) {
00155          if (osp->cacount < MAX_CERTS) {
00156             if (v->value[0] == '/')
00157                ast_copy_string(osp->cacerts[osp->cacount], v->value, sizeof(osp->cacerts[0]));
00158             else
00159                snprintf(osp->cacerts[osp->cacount], sizeof(osp->cacerts[0]), "%s/%s", ast_config_AST_KEY_DIR, v->value);
00160             osp->cacount++;
00161          } else
00162             ast_log(LOG_WARNING, "Too many CA Certificates at line %d\n", v->lineno);
00163       } else if (!strcasecmp(v->name, "servicepoint")) {
00164          if (osp->spcount < MAX_SERVICEPOINTS) {
00165             ast_copy_string(osp->servicepoints[osp->spcount], v->value, sizeof(osp->servicepoints[0]));
00166             osp->spcount++;
00167          } else
00168             ast_log(LOG_WARNING, "Too many Service points at line %d\n", v->lineno);
00169       } else if (!strcasecmp(v->name, "maxconnections")) {
00170          if ((sscanf(v->value, "%30d", &x) == 1) && (x > 0) && (x <= 1000)) {
00171             osp->maxconnections = x;
00172          } else
00173             ast_log(LOG_WARNING, "maxconnections should be an integer from 1 to 1000, not '%s' at line %d\n", v->value, v->lineno);
00174       } else if (!strcasecmp(v->name, "retrydelay")) {
00175          if ((sscanf(v->value, "%30d", &x) == 1) && (x >= 0) && (x <= 10)) {
00176             osp->retrydelay = x;
00177          } else
00178             ast_log(LOG_WARNING, "retrydelay should be an integer from 0 to 10, not '%s' at line %d\n", v->value, v->lineno);
00179       } else if (!strcasecmp(v->name, "retrylimit")) {
00180          if ((sscanf(v->value, "%30d", &x) == 1) && (x >= 0) && (x <= 100)) {
00181             osp->retrylimit = x;
00182          } else
00183             ast_log(LOG_WARNING, "retrylimit should be an integer from 0 to 100, not '%s' at line %d\n", v->value, v->lineno);
00184       } else if (!strcasecmp(v->name, "timeout")) {
00185          if ((sscanf(v->value, "%30d", &x) == 1) && (x >= 200) && (x <= 10000)) {
00186             osp->timeout = x;
00187          } else
00188             ast_log(LOG_WARNING, "timeout should be an integer from 200 to 10000, not '%s' at line %d\n", v->value, v->lineno);
00189       } else if (!strcasecmp(v->name, "source")) {
00190          ast_copy_string(osp->source, v->value, sizeof(osp->source));
00191       }
00192       v = v->next;
00193    }
00194    if (osp->cacount < 1) {
00195       snprintf(osp->cacerts[osp->cacount], sizeof(osp->cacerts[0]), "%s/%s-cacert.pem", ast_config_AST_KEY_DIR, cat);
00196       osp->cacount++;
00197    }
00198    for (x=0;x<osp->cacount;x++)
00199       cacerts[x] = osp->cacerts[x];
00200    for (x=0;x<osp->spcount;x++)
00201       servicepoints[x] = osp->servicepoints[x];
00202    
00203    ast_mutex_lock(&osplock);
00204    osp->dead = 0;
00205    if (osp->handle > -1) {
00206       ast_log(LOG_DEBUG, "Deleting old handle for '%s'\n", osp->name);
00207       OSPPProviderDelete(osp->handle, 0);
00208    }
00209       
00210 
00211     length = 0;
00212    ast_log(LOG_DEBUG, "Loading private key for '%s' (%s)\n", osp->name, osp->localpvtkey);
00213     errorcode = loadPemPrivateKey(osp->localpvtkey,Reqbuf,&length);
00214     if (errorcode == 0)
00215     {
00216         privatekey.PrivateKeyData = Reqbuf;
00217         privatekey.PrivateKeyLength = length;
00218     }
00219     else
00220     {
00221          return -1;
00222     }
00223 
00224     length = 0;
00225    ast_log(LOG_DEBUG, "Loading local cert for '%s' (%s)\n", osp->name, osp->localcert);
00226     errorcode = loadPemCert(osp->localcert,LocalBuf,&length);
00227     if (errorcode == 0)
00228     {
00229         localcert.CertData = LocalBuf;
00230         localcert.CertDataLength = length;
00231     }
00232     else
00233     {
00234          return -1;
00235     }
00236 
00237     for (i=0;i<osp->cacount;i++)
00238     {
00239         length = 0;
00240       ast_log(LOG_DEBUG, "Loading CA cert %d for '%s' (%s)\n", i + 1, osp->name, osp->cacerts[i]);
00241         errorcode = loadPemCert(osp->cacerts[i],AuthBuf[i],&length);
00242         if (errorcode == 0)
00243         {
00244             TheAuthCert[i].CertData = AuthBuf[i];
00245             TheAuthCert[i].CertDataLength = length;
00246             authCerts[i] = &(TheAuthCert[i]);
00247         }
00248         else
00249         {
00250          return -1;        
00251       }
00252     }
00253    
00254    ast_log(LOG_DEBUG, "Creating provider handle for '%s'\n", osp->name);
00255    
00256    ast_log(LOG_DEBUG, "Service point '%s %d'\n", servicepoints[0], osp->spcount);
00257    
00258    if (OSPPProviderNew(osp->spcount, 
00259                    servicepoints, 
00260                   NULL, 
00261                   "localhost", 
00262                   &privatekey, 
00263                   &localcert, 
00264                   osp->cacount, 
00265                   (const OSPTCERT **)authCerts, 
00266                   1, 
00267                   300, 
00268                   osp->maxconnections, 
00269                   1, 
00270                   osp->retrydelay, 
00271                   osp->retrylimit, 
00272                   osp->timeout, 
00273                   "", 
00274                   "", 
00275                   &osp->handle)) {
00276       ast_log(LOG_WARNING, "Unable to initialize provider '%s'\n", cat);
00277       osp->dead = 1;
00278    }
00279    
00280    if (mallocd) {
00281       osp->next = providers;
00282       providers = osp;
00283    }
00284    ast_mutex_unlock(&osplock);   
00285    return 0;
00286 }

int reload ( void   ) 

Reload stuff.

This function is where any reload routines take place. Re-read config files, change signalling, whatever is appropriate on a reload.

Returns:
The return value is not used.

Definition at line 852 of file res_osp.c.

References ast_log(), config_load(), and LOG_NOTICE.

Referenced by ast_module_reload().

00853 {
00854    config_load();
00855    ast_log(LOG_NOTICE, "XXX Should reload OSP config XXX\n");
00856    return 0;
00857 }

static int show_osp ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 288 of file res_osp.c.

References ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), osp_provider::cacerts, osp_provider::cacount, osp_provider::handle, osp_provider::localcert, osp_provider::localpvtkey, osp_provider::maxconnections, osp_provider::name, osp_provider::next, RESULT_SHOWUSAGE, RESULT_SUCCESS, osp_provider::retrydelay, osp_provider::retrylimit, osp_provider::servicepoints, osp_provider::source, osp_provider::spcount, and osp_provider::timeout.

00289 {
00290    struct osp_provider *osp;
00291    char *search = NULL;
00292    int x;
00293    int found = 0;
00294    char *tokenalgo;
00295 
00296    if ((argc < 2) || (argc > 3))
00297       return RESULT_SHOWUSAGE;
00298    if (argc > 2)
00299       search = argv[2];
00300    if (!search) {
00301       switch (tokenformat) {
00302          case TOKEN_ALGO_BOTH:
00303             tokenalgo = "Both";
00304             break;
00305          case TOKEN_ALGO_UNSIGNED:
00306             tokenalgo = "Unsigned";
00307             break;
00308          case TOKEN_ALGO_SIGNED:
00309          default:
00310             tokenalgo = "Signed";
00311             break;
00312       }
00313       ast_cli(fd, "OSP: %s %s %s\n", initialized ? "Initialized" : "Uninitialized", hardware ? "Accelerated" : "Normal", tokenalgo);
00314    }
00315 
00316    ast_mutex_lock(&osplock);
00317    osp = providers;
00318    while(osp) {
00319       if (!search || !strcasecmp(osp->name, search)) {
00320          if (found)
00321             ast_cli(fd, "\n");
00322          ast_cli(fd, " == OSP Provider '%s' ==\n", osp->name);
00323          ast_cli(fd, "Local Private Key: %s\n", osp->localpvtkey);
00324          ast_cli(fd, "Local Certificate: %s\n", osp->localcert);
00325          for (x=0;x<osp->cacount;x++)
00326             ast_cli(fd, "CA Certificate %d:  %s\n", x + 1, osp->cacerts[x]);
00327          for (x=0;x<osp->spcount;x++)
00328             ast_cli(fd, "Service Point %d:   %s\n", x + 1, osp->servicepoints[x]);
00329          ast_cli(fd, "Max Connections:   %d\n", osp->maxconnections);
00330          ast_cli(fd, "Retry Delay:       %d seconds\n", osp->retrydelay);
00331          ast_cli(fd, "Retry Limit:       %d\n", osp->retrylimit);
00332          ast_cli(fd, "Timeout:           %d milliseconds\n", osp->timeout);
00333          ast_cli(fd, "Source:            %s\n", strlen(osp->source) ? osp->source : "<unspecified>");
00334          ast_cli(fd, "OSP Handle:        %d\n", osp->handle);
00335          found++;
00336       }
00337       osp = osp->next;
00338    }
00339    ast_mutex_unlock(&osplock);
00340    if (!found) {
00341       if (search) 
00342          ast_cli(fd, "Unable to find OSP provider '%s'\n", search);
00343       else
00344          ast_cli(fd, "No OSP providers configured\n");
00345    }
00346    return RESULT_SUCCESS;
00347 }

int unload_module ( void   ) 

Cleanup all module structures, sockets, etc.

This is called at exit. Any registrations and memory allocations need to be unregistered and free'd here. Nothing else will do these for you (until exit).

Returns:
Zero on success, or non-zero on error.
Standard module functions ...

Definition at line 866 of file res_osp.c.

Referenced by load_module().

00867 {
00868    /* Can't unload this once we're loaded */
00869    return -1;
00870 }

int usecount ( void   ) 

Provides a usecount.

This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.

Returns:
The module's usecount.

Definition at line 877 of file res_osp.c.

00878 {
00879    /* We should never be unloaded */
00880    return 1;
00881 }


Variable Documentation

struct ast_cli_entry cli_show_osp [static]

Initial value:

 
{ { "show", "osp", NULL }, show_osp, "Displays OSP information", show_osp_usage }

Definition at line 849 of file res_osp.c.

int hardware = 0 [static]

Definition at line 77 of file res_osp.c.

int initialized = 0 [static]

Definition at line 76 of file res_osp.c.

struct osp_provider* providers [static]

Definition at line 97 of file res_osp.c.

char show_osp_usage[] [static]

Initial value:

 
"Usage: show osp\n"
"       Displays information on Open Settlement Protocol\n"

Definition at line 845 of file res_osp.c.

unsigned tokenformat = TOKEN_ALGO_SIGNED [static]

Definition at line 78 of file res_osp.c.


Generated on Wed Oct 28 15:49:17 2009 for Asterisk - the Open Source PBX by  doxygen 1.5.6