4 * SQL authentication/authorization modules for GNU Gatekeeper
6 * $Id: sqlauth.cxx,v 1.10 2006/04/14 13:56:19 willamowius Exp $
8 * Copyright (c) 2004, Michal Zygmuntowicz
10 * This work is published under the GNU Public License (GPL)
11 * see file COPYING for details.
12 * We also explicitely grant the right to link this code
13 * with the OpenH323 library.
15 #if defined(_WIN32) && (_MSC_VER <= 1200)
16 #pragma warning(disable:4786) // warning about too long debug symbol off
17 #pragma warning(disable:4284)
42 /// Generic SQL authenticator for H.235 enabled endpoints
43 class SQLPasswordAuth : public SimplePasswordAuth
46 /// build authenticator reading settings from the config
48 /// name for this authenticator and for the config section to read settings from
52 virtual ~SQLPasswordAuth();
55 /** Override from SimplePasswordAuth.
58 True if the password has been found for the given alias.
60 virtual bool GetPassword(
61 /// alias to check the password for
63 /// password string, if the match is found
69 SQLPasswordAuth(const SQLPasswordAuth&);
70 SQLPasswordAuth& operator=(const SQLPasswordAuth&);
73 /// connection to the SQL database
74 GkSQLConnection* m_sqlConn;
75 /// parametrized query string for password retrieval
79 /// Generic SQL authenticator for alias/IP based authentication
80 class SQLAliasAuth : public AliasAuth
83 /// build authenticator reading settings from the config
85 /// name for this authenticator and for the config section to read settings from
89 virtual ~SQLAliasAuth();
92 /** Get auth condition string for the given alias.
93 This implementation searches the SQL database for the string.
94 Override from AliasAuth.
97 The AliasAuth condition string for the given alias.
99 virtual bool GetAuthConditionString(
100 /// an alias the condition string is to be retrieved for
101 const PString& alias,
102 /// filled with auth condition string that has been found
108 SQLAliasAuth(const SQLAliasAuth&);
109 SQLAliasAuth& operator=(const SQLAliasAuth&);
112 /// connection to the SQL database
113 GkSQLConnection* m_sqlConn;
114 /// parametrized query string for the auth condition string retrieval
118 /// Generic SQL authenticator for non-password, SQL based authentication
119 class SQLAuth : public GkAuthenticator
122 enum SupportedChecks {
123 SQLAuthRasChecks = RasInfo<H225_RegistrationRequest>::flag
124 | RasInfo<H225_AdmissionRequest>::flag
125 | RasInfo<H225_LocationRequest>::flag,
126 SQLAuthMiscChecks = e_Setup | e_SetupUnreg
129 /// build authenticator reading settings from the config
131 /// name for this authenticator and for the config section to read settings from
132 const char* authName,
133 /// RAS check events supported by this module
134 unsigned supportedRasChecks = SQLAuthRasChecks,
135 /// Misc check events supported by this module
136 unsigned supportedMiscChecks = SQLAuthMiscChecks
141 /** Authenticate using data from RRQ RAS message.
144 #GkAuthenticator::Status enum# with the result of authentication.
147 /// RRQ RAS message to be authenticated
148 RasPDU<H225_RegistrationRequest>& rrqPdu,
149 /// authorization data (reject reason, ...)
150 RRQAuthData& authData
153 /** Authenticate using data from ARQ RAS message.
156 #GkAuthenticator::Status enum# with the result of authentication.
159 /// ARQ nessage to be authenticated
160 RasPDU<H225_AdmissionRequest> & arqPdu,
161 /// authorization data (call duration limit, reject reason, ...)
162 ARQAuthData& authData
165 /** Authenticate using data from LRQ RAS message.
168 #GkAuthenticator::Status enum# with the result of authentication.
171 RasPDU<H225_LocationRequest>& req,
172 unsigned& rejectReason
175 /** Authenticate using data from Q.931 Setup message.
178 #GkAuthenticator::Status enum# with the result of authentication.
181 /// Q.931/H.225 Setup message to be authenticated
183 /// authorization data (call duration limit, reject reason, ...)
184 SetupAuthData& authData
189 SQLAuth(const SQLAuth&);
190 SQLAuth& operator=(const SQLAuth&);
193 /// connection to the SQL database
194 GkSQLConnection* m_sqlConn;
195 /// parametrized query string for RRQ auth
197 /// parametrized query string for LRQ auth
199 /// parametrized query string for ARQ/Setup auth
206 /// a common wrapper for SELECT query execution and result retrieval
208 const PString &traceStr,
209 GkSQLConnection *conn,
210 const PString &query,
211 const std::map<PString, PString>& params,
212 GkSQLResult::ResultRow& resultRow,
219 PTRACE(2, traceStr << ": query failed - SQL connection not active");
223 if (query.IsEmpty()) {
224 PTRACE(2, traceStr << ": query failed - query string not configured");
228 GkSQLResult* result = conn->ExecuteQuery(query, params, timeout);
229 if (result == NULL) {
230 PTRACE(2, traceStr << ": query failed - timeout or fatal error");
234 if (!result->IsValid()) {
235 PTRACE(2, traceStr << ": query failed (" << result->GetErrorCode()
236 << ") - " << result->GetErrorMessage()
242 if (result->GetNumRows() < 1)
243 PTRACE(3, traceStr << ": query returned no rows");
244 else if (result->GetNumFields() < 1)
245 PTRACE(2, traceStr << ": bad-formed query - "
246 "no columns found in the result set"
248 else if (!result->FetchRow(resultRow) || resultRow.empty())
249 PTRACE(2, traceStr << ": query failed - could not fetch the result row");
259 inline GkSQLResult::ResultRow::iterator FindField(
260 GkSQLResult::ResultRow& result,
261 const PString& fieldName
264 GkSQLResult::ResultRow::iterator i = result.begin();
265 while (i != result.end() && i->second != fieldName)
273 SQLPasswordAuth::SQLPasswordAuth(
276 : SimplePasswordAuth(authName), m_sqlConn(NULL)
278 PConfig* cfg = GetConfig();
280 const PString driverName = cfg->GetString(authName, "Driver", "");
281 if (driverName.IsEmpty()) {
282 PTRACE(0, "SQLAUTH\t" << GetName() << " module creation failed: "
283 "no SQL driver selected"
285 PTRACE(0, "SQLAUTH\tFATAL: Shutting down");
286 RasServer::Instance()->Stop();
290 m_sqlConn = GkSQLConnection::Create(driverName, authName);
291 if (m_sqlConn == NULL) {
292 PTRACE(0, "SQLAUTH\t" << GetName() << " module creation failed: "
293 "could not find " << driverName << " database driver"
295 PTRACE(0, "SQLAUTH\tFATAL: Shutting down");
296 RasServer::Instance()->Stop();
300 SetCacheTimeout(cfg->GetInteger(authName, "CacheTimeout", 0));
302 m_query = cfg->GetString(authName, "Query", "");
303 if (m_query.IsEmpty()) {
304 PTRACE(0, "SQLAUTH\t" << GetName() << " module creation failed: "
305 "no query configured"
307 PTRACE(0, "SQLAUTH\tFATAL: Shutting down");
308 RasServer::Instance()->Stop();
311 PTRACE(4, "SQLAUTH\t" << GetName() << " query: " << m_query);
313 if (!m_sqlConn->Initialize(cfg, authName)) {
314 PTRACE(0, "SQLAUTH\t" << GetName() << " module creation failed: "
315 "could not connect to the database"
321 SQLPasswordAuth::~SQLPasswordAuth()
326 bool SQLPasswordAuth::GetPassword(
327 const PString& alias,
331 GkSQLResult::ResultRow result;
332 std::map<PString, PString> params;
335 params["2"] = Toolkit::GKName();
336 params["g"] = Toolkit::GKName();
338 if (!RunQuery("SQLAUTH\t" + GetName() + "('" + alias + "')", m_sqlConn, m_query, params, result, -1))
341 password = result[0].first;
345 SQLAliasAuth::SQLAliasAuth(
348 : AliasAuth(authName), m_sqlConn(NULL)
350 PConfig* cfg = GetConfig();
352 const PString driverName = cfg->GetString(authName, "Driver", "");
353 if (driverName.IsEmpty()) {
354 PTRACE(0, "SQLAUTH\t" << GetName() << " module creation failed: "
355 "no SQL driver selected"
357 PTRACE(0, "SQLAUTH\tFATAL: Shutting down");
358 RasServer::Instance()->Stop();
362 m_sqlConn = GkSQLConnection::Create(driverName, authName);
363 if (m_sqlConn == NULL) {
364 PTRACE(0, "SQLAUTH\t" << GetName() << " module creation failed: "
365 "could not find " << driverName << " database driver"
367 PTRACE(0, "SQLAUTH\tFATAL: Shutting down");
368 RasServer::Instance()->Stop();
372 SetCacheTimeout(cfg->GetInteger(authName, "CacheTimeout", 0));
374 m_query = cfg->GetString(authName, "Query", "");
375 if (m_query.IsEmpty()) {
376 PTRACE(1, "SQLAUTH\t" << GetName() << " module creation failed: "
377 "no query configured"
379 PTRACE(0, "SQLAUTH\tFATAL: Shutting down");
380 RasServer::Instance()->Stop();
383 PTRACE(4, "SQLAUTH\t" << GetName() << " query: " << m_query);
385 if (!m_sqlConn->Initialize(cfg, authName)) {
386 PTRACE(0, "SQLAUTH\t" << GetName() << " module creation failed: "
387 "could not connect to the database"
393 SQLAliasAuth::~SQLAliasAuth()
398 bool SQLAliasAuth::GetAuthConditionString(
399 const PString& alias,
403 GkSQLResult::ResultRow result;
404 std::map<PString, PString> params;
407 params["2"] = Toolkit::GKName();
408 params["g"] = Toolkit::GKName();
410 if (!RunQuery("SQLAUTH\t" + GetName() + "('" + alias + "')", m_sqlConn, m_query, params, result, -1))
413 authCond = result[0].first;
419 const char* authName,
420 unsigned supportedRasChecks,
421 unsigned supportedMiscChecks
424 GkAuthenticator(authName, supportedRasChecks, supportedMiscChecks),
427 PConfig* cfg = GetConfig();
429 const PString driverName = cfg->GetString(authName, "Driver", "");
430 if (driverName.IsEmpty()) {
431 PTRACE(0, "SQLAUTH\t" << GetName() << " module creation failed: "
432 "no SQL driver selected"
434 PTRACE(0, "SQLAUTH\tFATAL: Shutting down");
435 RasServer::Instance()->Stop();
439 m_sqlConn = GkSQLConnection::Create(driverName, authName);
440 if (m_sqlConn == NULL) {
441 PTRACE(0, "SQLAUTH\t" << GetName() << " module creation failed: "
442 "could not find " << driverName << " database driver"
444 PTRACE(0, "SQLAUTH\tFATAL: Shutting down");
445 RasServer::Instance()->Stop();
449 m_regQuery = cfg->GetString(authName, "RegQuery", "");
450 if (m_regQuery.IsEmpty() && IsRasCheckEnabled(RasInfo<H225_RegistrationRequest>::flag)) {
451 PTRACE(1, "SQLAUTH\t" << GetName() << " module creation failed: "
452 "no RRQ query configured"
454 PTRACE(0, "SQLAUTH\tFATAL: Shutting down");
455 RasServer::Instance()->Stop();
457 } else if (!m_regQuery)
458 PTRACE(4, "SQLAUTH\t" << GetName() << " RRQ query: " << m_regQuery);
460 m_nbQuery = cfg->GetString(authName, "NbQuery", "");
461 if (m_nbQuery.IsEmpty() && IsRasCheckEnabled(RasInfo<H225_LocationRequest>::flag)) {
462 PTRACE(1, "SQLAUTH\t" << GetName() << " module creation failed: "
463 "no LRQ query configured"
465 PTRACE(0, "SQLAUTH\tFATAL: Shutting down");
466 RasServer::Instance()->Stop();
468 } else if (!m_nbQuery)
469 PTRACE(4, "SQLAUTH\t" << GetName() << " LRQ query: " << m_nbQuery);
471 m_callQuery = cfg->GetString(authName, "CallQuery", "");
472 if (m_callQuery.IsEmpty() && (IsRasCheckEnabled(RasInfo<H225_AdmissionRequest>::flag)
473 || IsMiscCheckEnabled(e_Setup) || IsMiscCheckEnabled(e_SetupUnreg))) {
474 PTRACE(1, "SQLAUTH\t" << GetName() << " module creation failed: "
475 "no ARQ/Setup query configured"
477 PTRACE(0, "SQLAUTH\tFATAL: Shutting down");
478 RasServer::Instance()->Stop();
480 } else if (!m_callQuery)
481 PTRACE(4, "SQLAUTH\t" << GetName() << " ARQ/Setup query: " << m_callQuery);
483 if (!m_sqlConn->Initialize(cfg, authName)) {
484 PTRACE(0, "SQLAUTH\t" << GetName() << " module creation failed: "
485 "could not connect to the database"
497 /// RRQ RAS message to be authenticated
498 RasPDU<H225_RegistrationRequest>& rrqPdu,
499 /// authorization data (reject reason, ...)
500 RRQAuthData& authData
503 H225_RegistrationRequest &rrq = rrqPdu;
504 std::map<PString, PString> params;
506 // get the username for User-Name attribute
507 params["u"] = GetUsername(rrqPdu);
508 params["g"] = Toolkit::GKName();
510 PIPSocket::Address addr = (rrqPdu.operator->())->m_peerAddr;
512 const PString traceStr = "SQLAUTH\t" + GetName() + "(RRQ from "
513 + addr.AsString() + " Username=" + params["u"]
515 params["callerip"] = addr.AsString();
517 addr = (rrqPdu.operator->())->m_localAddr;
518 params["gkip"] = addr.AsString();
520 if (rrq.HasOptionalField(H225_RegistrationRequest::e_terminalAlias)) {
522 for (PINDEX i = 0; i < rrq.m_terminalAlias.GetSize(); i++) {
525 aliasList += AsString(rrq.m_terminalAlias[i], FALSE);
527 params["aliases"] = aliasList;
530 GkSQLResult::ResultRow result;
531 if (!RunQuery(traceStr, m_sqlConn, m_regQuery, params, result, -1)) {
532 authData.m_rejectReason = H225_RegistrationRejectReason::e_resourceUnavailable;
533 return GetDefaultStatus();
536 if (!Toolkit::AsBool(result[0].first)) {
537 authData.m_rejectReason = H225_RegistrationRejectReason::e_securityDenial;
541 GkSQLResult::ResultRow::const_iterator iter = FindField(result, "billingmode");
542 if (iter != result.end()) {
543 const PString &s = iter->first;
545 if (strspn((const char*)s,"0123456789.") == (size_t)s.GetLength()) {
546 const int intVal = s.AsInteger();
548 authData.m_billingMode = H225_CallCreditServiceControl_billingMode::e_credit;
549 else if (intVal == 1 || intVal == 2)
550 authData.m_billingMode = H225_CallCreditServiceControl_billingMode::e_debit;
552 PTRACE(3, traceStr << " - invalid billingmode attribute '"
559 iter = FindField(result, "creditamount");
560 if (iter != result.end()) {
562 authData.m_amountString = iter->first;
565 iter = FindField(result, "aliases");
566 if (iter != result.end()) {
567 PStringArray aliases = iter->first.Tokenise(",");
568 if (aliases.GetSize() > 0
569 && rrq.HasOptionalField(H225_RegistrationRequest::e_terminalAlias)) {
571 while (i < rrq.m_terminalAlias.GetSize()) {
572 PINDEX j = aliases.GetStringsIndex(AsString(rrq.m_terminalAlias[i], FALSE));
573 if( j == P_MAX_INDEX )
574 rrq.m_terminalAlias.RemoveAt(i);
581 for (PINDEX i = 0; i < aliases.GetSize(); i++) {
582 if (rrq.HasOptionalField(H225_RegistrationRequest::e_terminalAlias))
583 rrq.m_terminalAlias.SetSize(rrq.m_terminalAlias.GetSize()+1);
585 rrq.IncludeOptionalField(H225_RegistrationRequest::e_terminalAlias);
586 rrq.m_terminalAlias.SetSize(1);
588 H323SetAliasAddress(aliases[i], rrq.m_terminalAlias[rrq.m_terminalAlias.GetSize()-1]);
596 /// ARQ nessage to be authenticated
597 RasPDU<H225_AdmissionRequest> & arqPdu,
598 /// authorization data (call duration limit, reject reason, ...)
599 ARQAuthData& authData
602 const H225_AdmissionRequest &arq = arqPdu;
603 std::map<PString, PString> params;
605 PIPSocket::Address addr = (arqPdu.operator->())->m_peerAddr;
607 const PString traceStr = "SQLAUTH\t" + GetName() + "(ARQ from "
608 + addr.AsString() + " CRV=" + PString(arq.m_callReferenceValue.GetValue() & 0x7fff)
610 params["callerip"] = addr.AsString();
612 // get the username for User-Name attribute
613 params["u"] = GetUsername(arqPdu, authData);
614 params["g"] = Toolkit::GKName();
616 addr = (arqPdu.operator->())->m_localAddr;
617 params["gkip"] = addr.AsString();
619 params["Calling-Station-Id"] = GetCallingStationId(arqPdu, authData);
620 params["Called-Station-Id"] = GetCalledStationId(arqPdu, authData);
621 params["Dialed-Number"] = GetDialedNumber(arqPdu, authData);
622 params["bandwidth"] = PString(arq.m_bandWidth.GetValue());
623 params["answer"] = arq.m_answerCall ? "1" : "0";
626 GkSQLResult::ResultRow result;
627 if (!RunQuery(traceStr, m_sqlConn, m_callQuery, params, result, -1)) {
628 authData.m_rejectReason = H225_AdmissionRejectReason::e_resourceUnavailable;
629 return GetDefaultStatus();
632 if (!Toolkit::AsBool(result[0].first)) {
633 authData.m_rejectReason = H225_AdmissionRejectReason::e_securityDenial;
637 GkSQLResult::ResultRow::const_iterator iter = FindField(result, "billingmode");
638 if (iter != result.end()) {
639 const PString &s = iter->first;
641 if (strspn((const char*)s,"0123456789.") == (size_t)s.GetLength()) {
642 const int intVal = s.AsInteger();
644 authData.m_billingMode = H225_CallCreditServiceControl_billingMode::e_credit;
645 else if (intVal == 1 || intVal == 2)
646 authData.m_billingMode = H225_CallCreditServiceControl_billingMode::e_debit;
648 PTRACE(3, traceStr << " - invalid billingmode attribute '"
655 iter = FindField(result, "creditamount");
656 if (iter != result.end()) {
658 authData.m_amountString = iter->first;
661 iter = FindField(result, "credittime");
662 if (iter != result.end()) {
663 const PString &s = iter->first;
664 if (s.GetLength() > 0
665 && strspn((const char*)s, "0123456789") == (size_t)s.GetLength()) {
666 PUInt64 limit = s.AsUnsigned64();
667 if (limit > PUInt64(std::numeric_limits<long>::max()))
668 authData.m_callDurationLimit = std::numeric_limits<long>::max();
670 authData.m_callDurationLimit = static_cast<long>(limit);
671 PTRACE(5, traceStr << " - duration limit set to "
672 << authData.m_callDurationLimit
674 if (authData.m_callDurationLimit == 0) {
675 authData.m_rejectReason = H225_AdmissionRejectReason::e_securityDenial;
681 iter = FindField(result, "redirectnumber");
682 if (iter != result.end()) {
683 const PString &s = iter->first;
685 authData.SetRouteToAlias(s);
686 PTRACE(5, traceStr << " - call redirected to the number " << s);
690 iter = FindField(result, "redirectip");
691 if (iter != result.end()) {
692 const PString &s = iter->first;
694 PStringArray tokens(s.Tokenise("; \t", FALSE));
695 for (PINDEX i = 0; i < tokens.GetSize(); ++i) {
696 PIPSocket::Address addr;
699 if (GetTransportAddress(tokens[i], GK_DEF_ENDPOINT_SIGNAL_PORT, addr, port)
700 && addr.IsValid() && port != 0) {
701 Route route("SQL", addr, port);
702 route.m_destEndpoint = RegistrationTable::Instance()->FindBySignalAdr(
703 SocketToH225TransportAddr(addr, port)
705 authData.m_destinationRoutes.push_back(route);
706 PTRACE(5, traceStr << " - call redirected to the address " <<
714 iter = FindField(result, "proxy");
715 if (iter != result.end()) {
716 const PString &s = iter->first;
718 authData.m_proxyMode = Toolkit::AsBool(s)
719 ? CallRec::ProxyEnabled : CallRec::ProxyDisabled;
720 PTRACE(5, traceStr << " - proxy mode "
721 << (authData.m_proxyMode == CallRec::ProxyEnabled ? "enabled" : "disabled")
730 RasPDU<H225_LocationRequest>& lrqPdu,
731 unsigned& rejectReason
734 H225_LocationRequest &lrq = lrqPdu;
735 std::map<PString, PString> params;
737 PIPSocket::Address addr = (lrqPdu.operator->())->m_peerAddr;
739 const PString traceStr = "SQLAUTH\t" + GetName() + "(LRQ from "
740 + addr.AsString() + ")";
741 params["nbip"] = addr.AsString();
742 params["nbid"] = RasServer::Instance()->GetNeighbors()->GetNeighborIdBySigAdr(addr);
743 params["g"] = Toolkit::GKName();
745 addr = (lrqPdu.operator->())->m_localAddr;
746 params["gkip"] = addr.AsString();
748 if (lrq.HasOptionalField(H225_LocationRequest::e_sourceInfo)) {
749 params["Calling-Station-Id"] = GetBestAliasAddressString(lrq.m_sourceInfo,
750 false, AliasAddressTagMask(H225_AliasAddress::e_dialedDigits)
751 | AliasAddressTagMask(H225_AliasAddress::e_partyNumber)
753 params["src-info"] = AsString(lrq.m_sourceInfo);
755 params["Called-Station-Id"] = GetBestAliasAddressString(lrq.m_destinationInfo,
756 false, AliasAddressTagMask(H225_AliasAddress::e_dialedDigits)
757 | AliasAddressTagMask(H225_AliasAddress::e_partyNumber)
759 params["dest-info"] = AsString(lrq.m_destinationInfo);
761 if (lrq.HasOptionalField(H225_LocationRequest::e_bandWidth))
762 params["bandwidth"] = PString(lrq.m_bandWidth.GetValue());
764 GkSQLResult::ResultRow result;
765 if (!RunQuery(traceStr, m_sqlConn, m_nbQuery, params, result, -1)) {
766 rejectReason = H225_LocationRejectReason::e_resourceUnavailable;
767 return GetDefaultStatus();
770 if (!Toolkit::AsBool(result[0].first)) {
771 rejectReason = H225_LocationRejectReason::e_securityDenial;
775 GkSQLResult::ResultRow::const_iterator iter = FindField(result, "destination");
776 if (iter != result.end()) {
777 PStringArray aliases = iter->first.Tokenise(",");
778 if (aliases.GetSize() > 0) {
780 while (i < lrq.m_destinationInfo.GetSize()) {
781 PINDEX j = aliases.GetStringsIndex(AsString(lrq.m_destinationInfo[i], FALSE));
782 if( j == P_MAX_INDEX )
783 lrq.m_destinationInfo.RemoveAt(i);
790 for (PINDEX i = 0; i < aliases.GetSize(); i++) {
791 const PINDEX sz = lrq.m_destinationInfo.GetSize();
792 lrq.m_destinationInfo.SetSize(sz + 1);
793 H323SetAliasAddress(aliases[i], lrq.m_destinationInfo[sz]);
801 /// Q.931/H.225 Setup message to be authenticated
803 /// authorization data (call duration limit, reject reason, ...)
804 SetupAuthData& authData
807 std::map<PString, PString> params;
809 PIPSocket::Address addr;
810 setup.GetPeerAddr(addr);
812 const PString traceStr = "SQLAUTH\t" + GetName() + "(Setup from "
813 + addr.AsString() + " CRV=" + PString(setup.GetQ931().GetCallReference())
815 params["callerip"] = addr.AsString();
817 // get the username for User-Name attribute
818 params["u"] = GetUsername(setup, authData);
819 params["g"] = Toolkit::GKName();
821 setup.GetLocalAddr(addr);
822 params["gkip"] = addr.AsString();
824 params["Calling-Station-Id"] = GetCallingStationId(setup, authData);
825 params["Called-Station-Id"] = GetCalledStationId(setup, authData);
826 params["Dialed-Number"] = GetDialedNumber(setup, authData);
827 params["answer"] = "0";
831 params["bandwidth"] = PString(authData.m_call->GetBandwidth());
833 GkSQLResult::ResultRow result;
834 if (!RunQuery(traceStr, m_sqlConn, m_callQuery, params, result, -1)) {
835 authData.m_rejectCause = Q931::TemporaryFailure;
836 return GetDefaultStatus();
839 if (!Toolkit::AsBool(result[0].first)) {
840 authData.m_rejectCause = Q931::CallRejected;
844 GkSQLResult::ResultRow::const_iterator iter = FindField(result, "credittime");
845 if (iter != result.end()) {
846 const PString &s = iter->first;
847 if (s.GetLength() > 0
848 && strspn((const char*)s, "0123456789") == (size_t)s.GetLength()) {
849 PUInt64 limit = s.AsUnsigned64();
850 if (limit > PUInt64(std::numeric_limits<long>::max()))
851 authData.m_callDurationLimit = std::numeric_limits<long>::max();
853 authData.m_callDurationLimit = static_cast<long>(limit);
854 PTRACE(5, traceStr << " - duration limit set to "
855 << authData.m_callDurationLimit
857 if (authData.m_callDurationLimit == 0) {
858 authData.m_rejectCause = Q931::CallRejected;
864 iter = FindField(result, "redirectnumber");
865 if (iter != result.end()) {
866 const PString &s = iter->first;
868 authData.SetRouteToAlias(s);
869 PTRACE(5, traceStr << " - call redirected to the number " << s);
873 iter = FindField(result, "redirectip");
874 if (iter != result.end()) {
875 const PString &s = iter->first;
877 PStringArray tokens(s.Tokenise("; \t", FALSE));
878 for (PINDEX i = 0; i < tokens.GetSize(); ++i) {
879 PIPSocket::Address addr;
882 if (GetTransportAddress(tokens[i], GK_DEF_ENDPOINT_SIGNAL_PORT, addr, port)
883 && addr.IsValid() && port != 0) {
884 Route route("SQL", addr, port);
885 route.m_destEndpoint = RegistrationTable::Instance()->FindBySignalAdr(
886 SocketToH225TransportAddr(addr, port)
888 authData.m_destinationRoutes.push_back(route);
889 PTRACE(5, traceStr << " - call redirected to the address " <<
897 iter = FindField(result, "proxy");
898 if (iter != result.end()) {
899 const PString &s = iter->first;
901 authData.m_proxyMode = Toolkit::AsBool(s)
902 ? CallRec::ProxyEnabled : CallRec::ProxyDisabled;
903 PTRACE(5, traceStr << " - proxy mode "
904 << (authData.m_proxyMode == CallRec::ProxyEnabled ? "enabled" : "disabled")
913 namespace { // anonymous namespace
914 GkAuthCreator<SQLPasswordAuth> SQLPasswordAuthCreator("SQLPasswordAuth");
915 GkAuthCreator<SQLAliasAuth> SQLAliasAuthCreator("SQLAliasAuth");
916 GkAuthCreator<SQLAuth> SQLAuthCreator("SQLAuth");
917 } // end of anonymous namespace