00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "asterisk.h"
00034
00035 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 86438 $")
00036
00037 #include <sys/types.h>
00038 #include <stdio.h>
00039 #include <string.h>
00040 #include <unistd.h>
00041 #include <errno.h>
00042 #include <osp/osp.h>
00043 #include <osp/osputils.h>
00044
00045 #include "asterisk/lock.h"
00046 #include "asterisk/config.h"
00047 #include "asterisk/utils.h"
00048 #include "asterisk/causes.h"
00049 #include "asterisk/channel.h"
00050 #include "asterisk/app.h"
00051 #include "asterisk/module.h"
00052 #include "asterisk/pbx.h"
00053 #include "asterisk/options.h"
00054 #include "asterisk/cli.h"
00055 #include "asterisk/logger.h"
00056 #include "asterisk/astosp.h"
00057
00058
00059 #define OSP_INTSTR_SIZE ((unsigned int)16)
00060 #define OSP_NORSTR_SIZE ((unsigned int)256)
00061 #define OSP_TOKSTR_SIZE ((unsigned int)4096)
00062
00063
00064 #define OSP_INVALID_HANDLE ((int)-1)
00065 #define OSP_CONFIG_FILE ((const char*)"osp.conf")
00066 #define OSP_GENERAL_CAT ((const char*)"general")
00067 #define OSP_DEF_PROVIDER ((const char*)"default")
00068 #define OSP_MAX_CERTS ((unsigned int)10)
00069 #define OSP_MAX_SRVS ((unsigned int)10)
00070 #define OSP_DEF_MAXCONNECTIONS ((unsigned int)20)
00071 #define OSP_MIN_MAXCONNECTIONS ((unsigned int)1)
00072 #define OSP_MAX_MAXCONNECTIONS ((unsigned int)1000)
00073 #define OSP_DEF_RETRYDELAY ((unsigned int)0)
00074 #define OSP_MIN_RETRYDELAY ((unsigned int)0)
00075 #define OSP_MAX_RETRYDELAY ((unsigned int)10)
00076 #define OSP_DEF_RETRYLIMIT ((unsigned int)2)
00077 #define OSP_MIN_RETRYLIMIT ((unsigned int)0)
00078 #define OSP_MAX_RETRYLIMIT ((unsigned int)100)
00079 #define OSP_DEF_TIMEOUT ((unsigned int)500)
00080 #define OSP_MIN_TIMEOUT ((unsigned int)200)
00081 #define OSP_MAX_TIMEOUT ((unsigned int)10000)
00082 #define OSP_DEF_AUTHPOLICY ((enum osp_authpolicy)OSP_AUTH_YES)
00083 #define OSP_AUDIT_URL ((const char*)"localhost")
00084 #define OSP_LOCAL_VALIDATION ((int)1)
00085 #define OSP_SSL_LIFETIME ((unsigned int)300)
00086 #define OSP_HTTP_PERSISTENCE ((int)1)
00087 #define OSP_CUSTOMER_ID ((const char*)"")
00088 #define OSP_DEVICE_ID ((const char*)"")
00089 #define OSP_DEF_DESTINATIONS ((unsigned int)5)
00090 #define OSP_DEF_TIMELIMIT ((unsigned int)0)
00091
00092
00093 enum osp_authpolicy {
00094 OSP_AUTH_NO,
00095 OSP_AUTH_YES,
00096 OSP_AUTH_EXCLUSIVE
00097 };
00098
00099
00100 struct osp_provider {
00101 char name[OSP_NORSTR_SIZE];
00102 char privatekey[OSP_NORSTR_SIZE];
00103 char localcert[OSP_NORSTR_SIZE];
00104 unsigned int cacount;
00105 char cacerts[OSP_MAX_CERTS][OSP_NORSTR_SIZE];
00106 unsigned int spcount;
00107 char srvpoints[OSP_MAX_SRVS][OSP_NORSTR_SIZE];
00108 int maxconnections;
00109 int retrydelay;
00110 int retrylimit;
00111 int timeout;
00112 char source[OSP_NORSTR_SIZE];
00113 enum osp_authpolicy authpolicy;
00114 OSPTPROVHANDLE handle;
00115 struct osp_provider* next;
00116 };
00117
00118
00119 struct osp_result {
00120 int inhandle;
00121 int outhandle;
00122 unsigned int intimelimit;
00123 unsigned int outtimelimit;
00124 char tech[20];
00125 char dest[OSP_NORSTR_SIZE];
00126 char calling[OSP_NORSTR_SIZE];
00127 char token[OSP_TOKSTR_SIZE];
00128 unsigned int numresults;
00129 };
00130
00131
00132 AST_MUTEX_DEFINE_STATIC(osplock);
00133 static int osp_initialized = 0;
00134 static int osp_hardware = 0;
00135 static struct osp_provider* ospproviders = NULL;
00136 static unsigned int osp_tokenformat = TOKEN_ALGO_SIGNED;
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146 static int osp_create_provider(struct ast_config* cfg, const char* provider)
00147 {
00148 int res;
00149 unsigned int t, i, j;
00150 struct osp_provider* p;
00151 struct ast_variable* v;
00152 OSPTPRIVATEKEY privatekey;
00153 OSPTCERT localcert;
00154 const char* psrvpoints[OSP_MAX_SRVS];
00155 OSPTCERT cacerts[OSP_MAX_CERTS];
00156 const OSPTCERT* pcacerts[OSP_MAX_CERTS];
00157 int error = OSPC_ERR_NO_ERROR;
00158
00159 if (!(p = ast_calloc(1, sizeof(*p)))) {
00160 ast_log(LOG_ERROR, "Out of memory\n");
00161 return -1;
00162 }
00163
00164 ast_copy_string(p->name, provider, sizeof(p->name));
00165 snprintf(p->privatekey, sizeof(p->privatekey), "%s/%s-privatekey.pem", ast_config_AST_KEY_DIR, provider);
00166 snprintf(p->localcert, sizeof(p->localcert), "%s/%s-localcert.pem", ast_config_AST_KEY_DIR, provider);
00167 p->maxconnections = OSP_DEF_MAXCONNECTIONS;
00168 p->retrydelay = OSP_DEF_RETRYDELAY;
00169 p->retrylimit = OSP_DEF_RETRYLIMIT;
00170 p->timeout = OSP_DEF_TIMEOUT;
00171 p->authpolicy = OSP_DEF_AUTHPOLICY;
00172 p->handle = OSP_INVALID_HANDLE;
00173
00174 v = ast_variable_browse(cfg, provider);
00175 while(v) {
00176 if (!strcasecmp(v->name, "privatekey")) {
00177 if (v->value[0] == '/') {
00178 ast_copy_string(p->privatekey, v->value, sizeof(p->privatekey));
00179 } else {
00180 snprintf(p->privatekey, sizeof(p->privatekey), "%s/%s", ast_config_AST_KEY_DIR, v->value);
00181 }
00182 ast_log(LOG_DEBUG, "OSP: privatekey '%s'\n", p->privatekey);
00183 } else if (!strcasecmp(v->name, "localcert")) {
00184 if (v->value[0] == '/') {
00185 ast_copy_string(p->localcert, v->value, sizeof(p->localcert));
00186 } else {
00187 snprintf(p->localcert, sizeof(p->localcert), "%s/%s", ast_config_AST_KEY_DIR, v->value);
00188 }
00189 ast_log(LOG_DEBUG, "OSP: localcert '%s'\n", p->localcert);
00190 } else if (!strcasecmp(v->name, "cacert")) {
00191 if (p->cacount < OSP_MAX_CERTS) {
00192 if (v->value[0] == '/') {
00193 ast_copy_string(p->cacerts[p->cacount], v->value, sizeof(p->cacerts[0]));
00194 } else {
00195 snprintf(p->cacerts[p->cacount], sizeof(p->cacerts[0]), "%s/%s", ast_config_AST_KEY_DIR, v->value);
00196 }
00197 ast_log(LOG_DEBUG, "OSP: cacert[%d]: '%s'\n", p->cacount, p->cacerts[p->cacount]);
00198 p->cacount++;
00199 } else {
00200 ast_log(LOG_WARNING, "OSP: Too many CA Certificates at line %d\n", v->lineno);
00201 }
00202 } else if (!strcasecmp(v->name, "servicepoint")) {
00203 if (p->spcount < OSP_MAX_SRVS) {
00204 ast_copy_string(p->srvpoints[p->spcount], v->value, sizeof(p->srvpoints[0]));
00205 ast_log(LOG_DEBUG, "OSP: servicepoint[%d]: '%s'\n", p->spcount, p->srvpoints[p->spcount]);
00206 p->spcount++;
00207 } else {
00208 ast_log(LOG_WARNING, "OSP: Too many Service Points at line %d\n", v->lineno);
00209 }
00210 } else if (!strcasecmp(v->name, "maxconnections")) {
00211 if ((sscanf(v->value, "%d", &t) == 1) && (t >= OSP_MIN_MAXCONNECTIONS) && (t <= OSP_MAX_MAXCONNECTIONS)) {
00212 p->maxconnections = t;
00213 ast_log(LOG_DEBUG, "OSP: maxconnections '%d'\n", t);
00214 } else {
00215 ast_log(LOG_WARNING, "OSP: maxconnections should be an integer from %d to %d, not '%s' at line %d\n",
00216 OSP_MIN_MAXCONNECTIONS, OSP_MAX_MAXCONNECTIONS, v->value, v->lineno);
00217 }
00218 } else if (!strcasecmp(v->name, "retrydelay")) {
00219 if ((sscanf(v->value, "%d", &t) == 1) && (t >= OSP_MIN_RETRYDELAY) && (t <= OSP_MAX_RETRYDELAY)) {
00220 p->retrydelay = t;
00221 ast_log(LOG_DEBUG, "OSP: retrydelay '%d'\n", t);
00222 } else {
00223 ast_log(LOG_WARNING, "OSP: retrydelay should be an integer from %d to %d, not '%s' at line %d\n",
00224 OSP_MIN_RETRYDELAY, OSP_MAX_RETRYDELAY, v->value, v->lineno);
00225 }
00226 } else if (!strcasecmp(v->name, "retrylimit")) {
00227 if ((sscanf(v->value, "%d", &t) == 1) && (t >= OSP_MIN_RETRYLIMIT) && (t <= OSP_MAX_RETRYLIMIT)) {
00228 p->retrylimit = t;
00229 ast_log(LOG_DEBUG, "OSP: retrylimit '%d'\n", t);
00230 } else {
00231 ast_log(LOG_WARNING, "OSP: retrylimit should be an integer from %d to %d, not '%s' at line %d\n",
00232 OSP_MIN_RETRYLIMIT, OSP_MAX_RETRYLIMIT, v->value, v->lineno);
00233 }
00234 } else if (!strcasecmp(v->name, "timeout")) {
00235 if ((sscanf(v->value, "%d", &t) == 1) && (t >= OSP_MIN_TIMEOUT) && (t <= OSP_MAX_TIMEOUT)) {
00236 p->timeout = t;
00237 ast_log(LOG_DEBUG, "OSP: timeout '%d'\n", t);
00238 } else {
00239 ast_log(LOG_WARNING, "OSP: timeout should be an integer from %d to %d, not '%s' at line %d\n",
00240 OSP_MIN_TIMEOUT, OSP_MAX_TIMEOUT, v->value, v->lineno);
00241 }
00242 } else if (!strcasecmp(v->name, "source")) {
00243 ast_copy_string(p->source, v->value, sizeof(p->source));
00244 ast_log(LOG_DEBUG, "OSP: source '%s'\n", p->source);
00245 } else if (!strcasecmp(v->name, "authpolicy")) {
00246 if ((sscanf(v->value, "%d", &t) == 1) && ((t == OSP_AUTH_NO) || (t == OSP_AUTH_YES) || (t == OSP_AUTH_EXCLUSIVE))) {
00247 p->authpolicy = t;
00248 ast_log(LOG_DEBUG, "OSP: authpolicy '%d'\n", t);
00249 } else {
00250 ast_log(LOG_WARNING, "OSP: authpolicy should be %d, %d or %d, not '%s' at line %d\n",
00251 OSP_AUTH_NO, OSP_AUTH_YES, OSP_AUTH_EXCLUSIVE, v->value, v->lineno);
00252 }
00253 }
00254 v = v->next;
00255 }
00256
00257 error = OSPPUtilLoadPEMPrivateKey((unsigned char *) p->privatekey, &privatekey);
00258 if (error != OSPC_ERR_NO_ERROR) {
00259 ast_log(LOG_WARNING, "OSP: Unable to load privatekey '%s', error '%d'\n", p->privatekey, error);
00260 free(p);
00261 return 0;
00262 }
00263
00264 error = OSPPUtilLoadPEMCert((unsigned char *) p->localcert, &localcert);
00265 if (error != OSPC_ERR_NO_ERROR) {
00266 ast_log(LOG_WARNING, "OSP: Unable to load localcert '%s', error '%d'\n", p->localcert, error);
00267 if (privatekey.PrivateKeyData) {
00268 free(privatekey.PrivateKeyData);
00269 }
00270 free(p);
00271 return 0;
00272 }
00273
00274 if (p->cacount < 1) {
00275 snprintf(p->cacerts[p->cacount], sizeof(p->cacerts[0]), "%s/%s-cacert.pem", ast_config_AST_KEY_DIR, provider);
00276 ast_log(LOG_DEBUG, "OSP: cacert[%d]: '%s'\n", p->cacount, p->cacerts[p->cacount]);
00277 p->cacount++;
00278 }
00279 for (i = 0; i < p->cacount; i++) {
00280 error = OSPPUtilLoadPEMCert((unsigned char *) p->cacerts[i], &cacerts[i]);
00281 if (error != OSPC_ERR_NO_ERROR) {
00282 ast_log(LOG_WARNING, "OSP: Unable to load cacert '%s', error '%d'\n", p->cacerts[i], error);
00283 for (j = 0; j < i; j++) {
00284 if (cacerts[j].CertData) {
00285 free(cacerts[j].CertData);
00286 }
00287 }
00288 if (localcert.CertData) {
00289 free(localcert.CertData);
00290 }
00291 if (privatekey.PrivateKeyData) {
00292 free(privatekey.PrivateKeyData);
00293 }
00294 free(p);
00295 return 0;
00296 }
00297 pcacerts[i] = &cacerts[i];
00298 }
00299
00300 for (i = 0; i < p->spcount; i++) {
00301 psrvpoints[i] = p->srvpoints[i];
00302 }
00303
00304 error = OSPPProviderNew(p->spcount, psrvpoints, NULL, OSP_AUDIT_URL, &privatekey, &localcert, p->cacount, pcacerts, OSP_LOCAL_VALIDATION,
00305 OSP_SSL_LIFETIME, p->maxconnections, OSP_HTTP_PERSISTENCE, p->retrydelay, p->retrylimit,p->timeout, OSP_CUSTOMER_ID,
00306 OSP_DEVICE_ID, &p->handle);
00307 if (error != OSPC_ERR_NO_ERROR) {
00308 ast_log(LOG_WARNING, "OSP: Unable to create provider '%s', error '%d'\n", provider, error);
00309 free(p);
00310 res = -1;
00311 } else {
00312 ast_log(LOG_DEBUG, "OSP: provider '%s'\n", provider);
00313 ast_mutex_lock(&osplock);
00314 p->next = ospproviders;
00315 ospproviders = p;
00316 ast_mutex_unlock(&osplock);
00317 res = 1;
00318 }
00319
00320 for (i = 0; i < p->cacount; i++) {
00321 if (cacerts[i].CertData) {
00322 free(cacerts[i].CertData);
00323 }
00324 }
00325 if (localcert.CertData) {
00326 free(localcert.CertData);
00327 }
00328 if (privatekey.PrivateKeyData) {
00329 free(privatekey.PrivateKeyData);
00330 }
00331
00332 return res;
00333 }
00334
00335
00336
00337
00338
00339
00340
00341 static int osp_get_policy(const char* provider, int* policy)
00342 {
00343 int res = 0;
00344 struct osp_provider* p;
00345
00346 ast_mutex_lock(&osplock);
00347 p = ospproviders;
00348 while(p) {
00349 if (!strcasecmp(p->name, provider)) {
00350 *policy = p->authpolicy;
00351 ast_log(LOG_DEBUG, "OSP: authpolicy '%d'\n", *policy);
00352 res = 1;
00353 break;
00354 }
00355 p = p->next;
00356 }
00357 ast_mutex_unlock(&osplock);
00358
00359 return res;
00360 }
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370 static int osp_create_transaction(const char* provider, int* transaction, unsigned int sourcesize, char* source)
00371 {
00372 int res = 0;
00373 struct osp_provider* p;
00374 int error;
00375
00376 ast_mutex_lock(&osplock);
00377 p = ospproviders;
00378 while(p) {
00379 if (!strcasecmp(p->name, provider)) {
00380 error = OSPPTransactionNew(p->handle, transaction);
00381 if (error == OSPC_ERR_NO_ERROR) {
00382 ast_log(LOG_DEBUG, "OSP: transaction '%d'\n", *transaction);
00383 ast_copy_string(source, p->source, sourcesize);
00384 ast_log(LOG_DEBUG, "OSP: source '%s'\n", source);
00385 res = 1;
00386 } else {
00387 *transaction = OSP_INVALID_HANDLE;
00388 ast_log(LOG_DEBUG, "OSP: Unable to create transaction handle, error '%d'\n", error);
00389 res = -1;
00390 }
00391 break;
00392 }
00393 p = p->next;
00394 }
00395 ast_mutex_unlock(&osplock);
00396
00397 return res;
00398 }
00399
00400
00401
00402
00403
00404
00405
00406 static void osp_convert_address(
00407 const char* src,
00408 char* dst,
00409 int buffersize)
00410 {
00411 struct in_addr inp;
00412
00413 if (inet_aton(src, &inp) != 0) {
00414 snprintf(dst, buffersize, "[%s]", src);
00415 } else {
00416 snprintf(dst, buffersize, "%s", src);
00417 }
00418 }
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431 static int osp_validate_token(int transaction, const char* source, const char* dest, const char* calling, const char* called, const char* token, unsigned int* timelimit)
00432 {
00433 int res;
00434 int tokenlen;
00435 unsigned char tokenstr[OSP_TOKSTR_SIZE];
00436 char src[OSP_NORSTR_SIZE];
00437 char dst[OSP_NORSTR_SIZE];
00438 unsigned int authorised;
00439 unsigned int dummy = 0;
00440 int error;
00441
00442 tokenlen = ast_base64decode(tokenstr, token, strlen(token));
00443 osp_convert_address(source, src, sizeof(src));
00444 osp_convert_address(dest, dst, sizeof(dst));
00445 error = OSPPTransactionValidateAuthorisation(
00446 transaction,
00447 src, dst, NULL, NULL,
00448 calling ? calling : "", OSPC_E164,
00449 called, OSPC_E164,
00450 0, NULL,
00451 tokenlen, (char *) tokenstr,
00452 &authorised,
00453 timelimit,
00454 &dummy, NULL,
00455 osp_tokenformat);
00456 if (error != OSPC_ERR_NO_ERROR) {
00457 ast_log(LOG_DEBUG, "OSP: Unable to validate inbound token\n");
00458 res = -1;
00459 } else if (authorised) {
00460 ast_log(LOG_DEBUG, "OSP: Authorised\n");
00461 res = 1;
00462 } else {
00463 ast_log(LOG_DEBUG, "OSP: Unauthorised\n");
00464 res = 0;
00465 }
00466
00467 return res;
00468 }
00469
00470
00471
00472
00473
00474
00475
00476 static unsigned int osp_choose_timelimit(unsigned int in, unsigned int out)
00477 {
00478 if (in == OSP_DEF_TIMELIMIT) {
00479 return out;
00480 } else if (out == OSP_DEF_TIMELIMIT) {
00481 return in;
00482 } else {
00483 return in < out ? in : out;
00484 }
00485 }
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498 static int osp_check_destination(const char* called, const char* calling, char* destination, unsigned int tokenlen, const char* token, enum OSPEFAILREASON* reason, struct osp_result* result)
00499 {
00500 int res;
00501 OSPE_DEST_OSP_ENABLED enabled;
00502 OSPE_DEST_PROT protocol;
00503 int error;
00504
00505 if (strlen(destination) <= 2) {
00506 ast_log(LOG_DEBUG, "OSP: Wrong destination format '%s'\n", destination);
00507 *reason = OSPC_FAIL_NORMAL_UNSPECIFIED;
00508 return -1;
00509 }
00510
00511 if ((error = OSPPTransactionIsDestOSPEnabled(result->outhandle, &enabled)) != OSPC_ERR_NO_ERROR) {
00512 ast_log(LOG_DEBUG, "OSP: Unable to get destination OSP version, error '%d'\n", error);
00513 *reason = OSPC_FAIL_NORMAL_UNSPECIFIED;
00514 return -1;
00515 }
00516
00517 if (enabled == OSPE_OSP_FALSE) {
00518 result->token[0] = '\0';
00519 } else {
00520 ast_base64encode(result->token, (const unsigned char *) token, tokenlen, sizeof(result->token) - 1);
00521 }
00522
00523 if ((error = OSPPTransactionGetDestProtocol(result->outhandle, &protocol)) != OSPC_ERR_NO_ERROR) {
00524 ast_log(LOG_DEBUG, "OSP: Unable to get destination protocol, error '%d'\n", error);
00525 *reason = OSPC_FAIL_NORMAL_UNSPECIFIED;
00526 result->token[0] = '\0';
00527 return -1;
00528 }
00529
00530 res = 1;
00531
00532 destination[strlen(destination) - 1] = '\0';
00533 switch(protocol) {
00534 case OSPE_DEST_PROT_H323_SETUP:
00535 ast_log(LOG_DEBUG, "OSP: protocol '%d'\n", protocol);
00536 ast_copy_string(result->tech, "H323", sizeof(result->tech));
00537 snprintf(result->dest, sizeof(result->dest), "%s@%s", called, destination + 1);
00538 ast_copy_string(result->calling, calling, sizeof(result->calling));
00539 break;
00540 case OSPE_DEST_PROT_SIP:
00541 ast_log(LOG_DEBUG, "OSP: protocol '%d'\n", protocol);
00542 ast_copy_string(result->tech, "SIP", sizeof(result->tech));
00543 snprintf(result->dest, sizeof(result->dest), "%s@%s", called, destination + 1);
00544 ast_copy_string(result->calling, calling, sizeof(result->calling));
00545 break;
00546 case OSPE_DEST_PROT_IAX:
00547 ast_log(LOG_DEBUG, "OSP: protocol '%d'\n", protocol);
00548 ast_copy_string(result->tech, "IAX", sizeof(result->tech));
00549 snprintf(result->dest, sizeof(result->dest), "%s@%s", called, destination + 1);
00550 ast_copy_string(result->calling, calling, sizeof(result->calling));
00551 break;
00552 default:
00553 ast_log(LOG_DEBUG, "OSP: Unknown protocol '%d'\n", protocol);
00554 *reason = OSPC_FAIL_PROTOCOL_ERROR;
00555 result->token[0] = '\0';
00556 res = 0;
00557 }
00558
00559 return res;
00560 }
00561
00562
00563
00564
00565
00566
00567 static enum OSPEFAILREASON asterisk2osp(int cause)
00568 {
00569 return (enum OSPEFAILREASON)cause;
00570 }
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583 static int osp_auth(const char* provider, int* transaction, const char* source, const char* calling, const char* called, const char* token, unsigned int* timelimit)
00584 {
00585 int res;
00586 int policy = OSP_AUTH_YES;
00587 char dest[OSP_NORSTR_SIZE];
00588
00589 *transaction = OSP_INVALID_HANDLE;
00590 *timelimit = OSP_DEF_TIMELIMIT;
00591 res = osp_get_policy(provider, &policy);
00592 if (!res) {
00593 ast_log(LOG_DEBUG, "OSP: Unabe to find OSP authentication policy\n");
00594 return res;
00595 }
00596
00597 switch (policy) {
00598 case OSP_AUTH_NO:
00599 res = 1;
00600 break;
00601 case OSP_AUTH_EXCLUSIVE:
00602 if (ast_strlen_zero(token)) {
00603 res = 0;
00604 } else if ((res = osp_create_transaction(provider, transaction, sizeof(dest), dest)) <= 0) {
00605 ast_log(LOG_DEBUG, "OSP: Unable to generate transaction handle\n");
00606 *transaction = OSP_INVALID_HANDLE;
00607 res = 0;
00608 } else if((res = osp_validate_token(*transaction, source, dest, calling, called, token, timelimit)) <= 0) {
00609 OSPPTransactionRecordFailure(*transaction, OSPC_FAIL_CALL_REJECTED);
00610 }
00611 break;
00612 case OSP_AUTH_YES:
00613 default:
00614 if (ast_strlen_zero(token)) {
00615 res = 1;
00616 } else if ((res = osp_create_transaction(provider, transaction, sizeof(dest), dest)) <= 0) {
00617 ast_log(LOG_DEBUG, "OSP: Unable to generate transaction handle\n");
00618 *transaction = OSP_INVALID_HANDLE;
00619 res = 0;
00620 } else if((res = osp_validate_token(*transaction, source, dest, calling, called, token, timelimit)) <= 0) {
00621 OSPPTransactionRecordFailure(*transaction, OSPC_FAIL_CALL_REJECTED);
00622 }
00623 break;
00624 }
00625
00626 return res;
00627 }
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638 static int osp_lookup(const char* provider, const char* srcdev, const char* calling, const char* called, struct osp_result* result)
00639 {
00640 int res;
00641 char source[OSP_NORSTR_SIZE];
00642 unsigned int callidlen;
00643 char callid[OSPC_CALLID_MAXSIZE];
00644 char callingnum[OSP_NORSTR_SIZE];
00645 char callednum[OSP_NORSTR_SIZE];
00646 char destination[OSP_NORSTR_SIZE];
00647 unsigned int tokenlen;
00648 char token[OSP_TOKSTR_SIZE];
00649 char src[OSP_NORSTR_SIZE];
00650 char dev[OSP_NORSTR_SIZE];
00651 unsigned int dummy = 0;
00652 enum OSPEFAILREASON reason;
00653 int error;
00654
00655 result->outhandle = OSP_INVALID_HANDLE;
00656 result->tech[0] = '\0';
00657 result->dest[0] = '\0';
00658 result->calling[0] = '\0';
00659 result->token[0] = '\0';
00660 result->numresults = 0;
00661 result->outtimelimit = OSP_DEF_TIMELIMIT;
00662
00663 if ((res = osp_create_transaction(provider, &result->outhandle, sizeof(source), source)) <= 0) {
00664 ast_log(LOG_DEBUG, "OSP: Unable to generate transaction handle\n");
00665 result->outhandle = OSP_INVALID_HANDLE;
00666 if (result->inhandle != OSP_INVALID_HANDLE) {
00667 OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NORMAL_UNSPECIFIED);
00668 }
00669 return -1;
00670 }
00671
00672 osp_convert_address(source, src, sizeof(src));
00673 osp_convert_address(srcdev, dev, sizeof(dev));
00674 result->numresults = OSP_DEF_DESTINATIONS;
00675 error = OSPPTransactionRequestAuthorisation(result->outhandle, src, dev, calling ? calling : "",
00676 OSPC_E164, called, OSPC_E164, NULL, 0, NULL, NULL, &result->numresults, &dummy, NULL);
00677 if (error != OSPC_ERR_NO_ERROR) {
00678 ast_log(LOG_DEBUG, "OSP: Unable to request authorization\n");
00679 result->numresults = 0;
00680 if (result->inhandle != OSP_INVALID_HANDLE) {
00681 OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NORMAL_UNSPECIFIED);
00682 }
00683 return -1;
00684 }
00685
00686 if (!result->numresults) {
00687 ast_log(LOG_DEBUG, "OSP: No more destination\n");
00688 if (result->inhandle != OSP_INVALID_HANDLE) {
00689 OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NO_ROUTE_TO_DEST);
00690 }
00691 return 0;
00692 }
00693
00694 callidlen = sizeof(callid);
00695 tokenlen = sizeof(token);
00696 error = OSPPTransactionGetFirstDestination(result->outhandle, 0, NULL, NULL, &result->outtimelimit, &callidlen, callid,
00697 sizeof(callednum), callednum, sizeof(callingnum), callingnum, sizeof(destination), destination, 0, NULL, &tokenlen, token);
00698 if (error != OSPC_ERR_NO_ERROR) {
00699 ast_log(LOG_DEBUG, "OSP: Unable to get first route\n");
00700 result->numresults = 0;
00701 result->outtimelimit = OSP_DEF_TIMELIMIT;
00702 if (result->inhandle != OSP_INVALID_HANDLE) {
00703 OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NO_ROUTE_TO_DEST);
00704 }
00705 return -1;
00706 }
00707
00708 result->numresults--;
00709 result->outtimelimit = osp_choose_timelimit(result->intimelimit, result->outtimelimit);
00710 ast_log(LOG_DEBUG, "OSP: outtimelimit '%d'\n", result->outtimelimit);
00711 ast_log(LOG_DEBUG, "OSP: called '%s'\n", callednum);
00712 ast_log(LOG_DEBUG, "OSP: calling '%s'\n", callingnum);
00713 ast_log(LOG_DEBUG, "OSP: destination '%s'\n", destination);
00714 ast_log(LOG_DEBUG, "OSP: token size '%d'\n", tokenlen);
00715
00716 if ((res = osp_check_destination(callednum, callingnum, destination, tokenlen, token, &reason, result)) > 0) {
00717 return 1;
00718 }
00719
00720 if (!result->numresults) {
00721 ast_log(LOG_DEBUG, "OSP: No more destination\n");
00722 result->outtimelimit = OSP_DEF_TIMELIMIT;
00723 OSPPTransactionRecordFailure(result->outhandle, reason);
00724 if (result->inhandle != OSP_INVALID_HANDLE) {
00725 OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NO_ROUTE_TO_DEST);
00726 }
00727 return 0;
00728 }
00729
00730 while(result->numresults) {
00731 callidlen = sizeof(callid);
00732 tokenlen = sizeof(token);
00733 error = OSPPTransactionGetNextDestination(result->outhandle, reason, 0, NULL, NULL, &result->outtimelimit, &callidlen, callid,
00734 sizeof(callednum), callednum, sizeof(callingnum), callingnum, sizeof(destination), destination, 0, NULL, &tokenlen, token);
00735 if (error == OSPC_ERR_NO_ERROR) {
00736 result->numresults--;
00737 result->outtimelimit = osp_choose_timelimit(result->intimelimit, result->outtimelimit);
00738 ast_log(LOG_DEBUG, "OSP: outtimelimit '%d'\n", result->outtimelimit);
00739 ast_log(LOG_DEBUG, "OSP: called '%s'\n", callednum);
00740 ast_log(LOG_DEBUG, "OSP: calling '%s'\n", callingnum);
00741 ast_log(LOG_DEBUG, "OSP: destination '%s'\n", destination);
00742 ast_log(LOG_DEBUG, "OSP: token size '%d'\n", tokenlen);
00743 if ((res = osp_check_destination(callednum, callingnum, destination, tokenlen, token, &reason, result)) > 0) {
00744 break;
00745 } else if (!result->numresults) {
00746 ast_log(LOG_DEBUG, "OSP: No more destination\n");
00747 OSPPTransactionRecordFailure(result->outhandle, reason);
00748 if (result->inhandle != OSP_INVALID_HANDLE) {
00749 OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NO_ROUTE_TO_DEST);
00750 }
00751 res = 0;
00752 break;
00753 }
00754 } else {
00755 ast_log(LOG_DEBUG, "OSP: Unable to get route, error '%d'\n", error);
00756 result->numresults = 0;
00757 result->outtimelimit = OSP_DEF_TIMELIMIT;
00758 if (result->inhandle != OSP_INVALID_HANDLE) {
00759 OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NORMAL_UNSPECIFIED);
00760 }
00761 res = -1;
00762 break;
00763 }
00764 }
00765 return res;
00766 }
00767
00768
00769
00770
00771
00772
00773
00774 static int osp_next(int cause, struct osp_result* result)
00775 {
00776 int res;
00777 unsigned int callidlen;
00778 char callid[OSPC_CALLID_MAXSIZE];
00779 char callingnum[OSP_NORSTR_SIZE];
00780 char callednum[OSP_NORSTR_SIZE];
00781 char destination[OSP_NORSTR_SIZE];
00782 unsigned int tokenlen;
00783 char token[OSP_TOKSTR_SIZE];
00784 enum OSPEFAILREASON reason;
00785 int error;
00786
00787 result->tech[0] = '\0';
00788 result->dest[0] = '\0';
00789 result->calling[0] = '\0';
00790 result->token[0] = '\0';
00791 result->outtimelimit = OSP_DEF_TIMELIMIT;
00792
00793 if (result->outhandle == OSP_INVALID_HANDLE) {
00794 ast_log(LOG_DEBUG, "OSP: Transaction handle undefined\n");
00795 result->numresults = 0;
00796 if (result->inhandle != OSP_INVALID_HANDLE) {
00797 OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NORMAL_UNSPECIFIED);
00798 }
00799 return -1;
00800 }
00801
00802 reason = asterisk2osp(cause);
00803
00804 if (!result->numresults) {
00805 ast_log(LOG_DEBUG, "OSP: No more destination\n");
00806 OSPPTransactionRecordFailure(result->outhandle, reason);
00807 if (result->inhandle != OSP_INVALID_HANDLE) {
00808 OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NO_ROUTE_TO_DEST);
00809 }
00810 return 0;
00811 }
00812
00813 while(result->numresults) {
00814 callidlen = sizeof(callid);
00815 tokenlen = sizeof(token);
00816 error = OSPPTransactionGetNextDestination(result->outhandle, reason, 0, NULL, NULL, &result->outtimelimit, &callidlen,
00817 callid, sizeof(callednum), callednum, sizeof(callingnum), callingnum, sizeof(destination), destination, 0, NULL, &tokenlen, token);
00818 if (error == OSPC_ERR_NO_ERROR) {
00819 result->numresults--;
00820 result->outtimelimit = osp_choose_timelimit(result->intimelimit, result->outtimelimit);
00821 ast_log(LOG_DEBUG, "OSP: outtimelimit '%d'\n", result->outtimelimit);
00822 ast_log(LOG_DEBUG, "OSP: called '%s'\n", callednum);
00823 ast_log(LOG_DEBUG, "OSP: calling '%s'\n", callingnum);
00824 ast_log(LOG_DEBUG, "OSP: destination '%s'\n", destination);
00825 ast_log(LOG_DEBUG, "OSP: token size '%d'\n", tokenlen);
00826 if ((res = osp_check_destination(callednum, callingnum, destination, tokenlen, token, &reason, result)) > 0) {
00827 res = 1;
00828 break;
00829 } else if (!result->numresults) {
00830 ast_log(LOG_DEBUG, "OSP: No more destination\n");
00831 OSPPTransactionRecordFailure(result->outhandle, reason);
00832 if (result->inhandle != OSP_INVALID_HANDLE) {
00833 OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NO_ROUTE_TO_DEST);
00834 }
00835 res = 0;
00836 break;
00837 }
00838 } else {
00839 ast_log(LOG_DEBUG, "OSP: Unable to get route, error '%d'\n", error);
00840 result->token[0] = '\0';
00841 result->numresults = 0;
00842 result->outtimelimit = OSP_DEF_TIMELIMIT;
00843 if (result->inhandle != OSP_INVALID_HANDLE) {
00844 OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NORMAL_UNSPECIFIED);
00845 }
00846 res = -1;
00847 break;
00848 }
00849 }
00850
00851 return res;
00852 }
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865 static int osp_finish(int handle, int recorded, int cause, time_t start, time_t connect, time_t end, unsigned int release)
00866 {
00867 int