Sync of SR with public.

git-svn-id: http://wush.net/svn/range/software/public/subscriberRegistry/trunk@6166 19bc5d8c-e614-43d4-8b26-e1612bc8e597
This commit is contained in:
Kurtis Heimerl 2013-08-13 23:45:19 +00:00
parent dd1d7d3109
commit baf5fdf717
52 changed files with 4029 additions and 141 deletions

12
COPYING
View File

@ -693,22 +693,28 @@ Interaction; Use with the GNU General Public License"). This exemption of
interfaces other than the GSM air interface from the requirements of Section 13
is an additional permission granted to you.
2. GSM "A5" cipher stream generation libraries
Notwithstanding any other provision of this License, you have
permission to link the Program with GSM "A5" cipher-stream generation
libraries provided under any license that allows redistribution of
those libraries in binary form, provided that the function of any such
library is limited to the generation of cipher-steam bits.
Non-Permissive Terms Supplementing The License
1. Trademarks.
"OpenBTS" is a trademark of Kestrel Signal Processing, Inc., registered with
"OpenBTS" is a trademark of Range Networks, Inc., registered with
the US Patent and Trademark Office. Your use of OpenBTS software under a GPL
license does not include the right to use the OpenBTS trademark in commerce.
This additional non-permissive term is consistent with Section 7 of the AGPLv3
license.
END OF ADDITIONAL TERMS
How to comply with Section 13 of the AGPLv3 license.
The recommended method for compliance with Section 13 of the AGPLv3 license is

View File

@ -8,20 +8,53 @@ CPPFLAGS=-g -Wall -Wno-deprecated
DESTDIR :=
all: sipauthserve
all: comp128 srmanager.cgi subscriberserver.cgi sipauthserve
comp128: comp128.c
g++ -o comp128 comp128.c
subscriberserver.cgi: subscriberserver.cpp $(LOCALLIBS)
g++ -o subscriberserver.cgi $(CPPFLAGS) $(INCLUDES) subscriberserver.cpp $(LIBS)
srmanager.cgi: srmanager.cpp $(LOCALLIBS)
g++ -o srmanager.cgi $(CPPFLAGS) $(INCLUDES) srmanager.cpp $(LIBS)
sipauthserve: sipauthserve.cpp $(LOCALLIBS)
g++ -o sipauthserve $(CPPFLAGS) $(INCLUDES) sipauthserve.cpp $(LIBS)
clean:
rm -f sipauthserve
rm -f comp128 subscriberserver.cgi srmanager.cgi sipauthserve test.SubscriberRegistry/test
rm -r -f *.dSYM
# this needs "local7.debug<at least one tab>/var/log/openbts.log" in /etc/syslog.conf
test: all
cd test.SubscriberRegistry; ./runtest
cd test.sipauthserve; ./runtest
cd test.srmanager; ./runtest
cd test.subscriberserver; ./runtest
just3: all
cd test.SubscriberRegistry; ./runtest
cd test.srmanager; ./runtest
cd test.subscriberserver; ./runtest
IPATH=$(DESTDIR)/usr/local/bin/
CGIPATH=$(DESTDIR)/var/cgi-bin/
OPATH=$(DESTDIR)/OpenBTS/
CONFIGPATH=$(DESTDIR)/etc/OpenBTS/
# specifically for boa web server
install: all
mkdir -p $(IPATH)
install comp128 $(IPATH)
install hexmapper $(IPATH)
install syslogextractor $(IPATH)
mkdir -p $(CGIPATH)
install -m +s -o root srmanager.cgi $(CGIPATH)
install -m +s -o root subscriberserver.cgi $(CGIPATH)
mkdir -p $(OPATH)
install comp128 $(OPATH)
install sipauthserve $(OPATH)
mkdir -p $(CONFIGPATH)
install configFiles/subscriberRegistryInit.sql $(CONFIGPATH)
install sipauthserve.example.sql $(CONFIGPATH)
install subscriberRegistry.example.sql $(CONFIGPATH)

View File

@ -173,7 +173,8 @@ int SubscriberRegistry::init()
LOG(EMERG) << dir << " does not exist";
mDB = NULL;
return 1;
}
}
mNumSQLTries=gConfig.getNum("Control.NumSQLTries");
int rc = sqlite3_open(ldb.c_str(),&mDB);
if (rc) {
LOG(EMERG) << "Cannot open SubscriberRegistry database: " << ldb << " error: " << sqlite3_errmsg(mDB);
@ -181,22 +182,26 @@ int SubscriberRegistry::init()
mDB = NULL;
return 1;
}
if (!sqlite3_command(mDB,createRRLPTable)) {
if (!sqlite3_command(mDB,createRRLPTable,mNumSQLTries)) {
LOG(EMERG) << "Cannot create RRLP table";
return 1;
}
if (!sqlite3_command(mDB,createDDTable)) {
if (!sqlite3_command(mDB,createDDTable,mNumSQLTries)) {
LOG(EMERG) << "Cannot create DIALDATA_TABLE table";
return 1;
}
if (!sqlite3_command(mDB,createRateTable)) {
if (!sqlite3_command(mDB,createRateTable,mNumSQLTries)) {
LOG(EMERG) << "Cannot create rate table";
return 1;
}
if (!sqlite3_command(mDB,createSBTable)) {
if (!sqlite3_command(mDB,createSBTable,mNumSQLTries)) {
LOG(EMERG) << "Cannot create SIP_BUDDIES table";
return 1;
}
// Set high-concurrency WAL mode.
if (!sqlite3_command(mDB,enableWAL,mNumSQLTries)) {
LOG(EMERG) << "Cannot enable WAL mode on database at " << ldb << ", error message: " << sqlite3_errmsg(mDB);
}
if (!getCLIDLocal("IMSI001010000000000")) {
// This is a test SIM provided with the BTS.
if (addUser("IMSI001010000000000", "2100") != SUCCESS) {
@ -213,21 +218,37 @@ SubscriberRegistry::~SubscriberRegistry()
if (mDB) sqlite3_close(mDB);
}
SubscriberRegistry::Status SubscriberRegistry::sqlHttp(const char *stmt, char **resultptr)
{
LOG(INFO) << stmt;
HttpQuery qry("sql");
qry.send("stmts", stmt);
if (!qry.http(false)) return FAILURE;
const char *res = qry.receive("res");
if (!res) return FAILURE;
*resultptr = strdup(res);
return SUCCESS;
}
SubscriberRegistry::Status SubscriberRegistry::sqlLocal(const char *query, char **resultptr)
{
LOG(INFO) << query;
if (!resultptr) {
if (!sqlite3_command(db(), query)) return FAILURE;
if (!sqlite3_command(db(), query, mNumSQLTries)) return FAILURE;
return SUCCESS;
}
sqlite3_stmt *stmt;
if (sqlite3_prepare_statement(db(), &stmt, query)) {
if (sqlite3_prepare_statement(db(), &stmt, query, mNumSQLTries)) {
LOG(ERR) << "sqlite3_prepare_statement problem with query \"" << query << "\"";
return FAILURE;
}
int src = sqlite3_run_query(db(), stmt);
int src = sqlite3_run_query(db(), stmt, mNumSQLTries);
if (src != SQLITE_ROW) {
sqlite3_finalize(stmt);
return FAILURE;
@ -258,6 +279,19 @@ char *SubscriberRegistry::sqlQuery(const char *unknownColumn, const char *table,
LOG(INFO) << "result = " << result;
return result;
}
// didn't find locally, so try over http
st = sqlHttp(os.str().c_str(), &result);
if ((st == SUCCESS) && result) {
// found over http but not locally, so cache locally
ostringstream os2;
os2 << "insert into " << table << "(" << knownColumn << ", " << unknownColumn << ") values (\"" <<
knownValue << "\",\"" << result << "\")";
// ignore whether it succeeds
sqlLocal(os2.str().c_str(), NULL);
LOG(INFO) << "result = " << result;
return result;
}
// didn't find locally or over http
LOG(INFO) << "not found: " << os.str();
return NULL;
}
@ -268,6 +302,7 @@ SubscriberRegistry::Status SubscriberRegistry::sqlUpdate(const char *stmt)
{
LOG(INFO) << stmt;
SubscriberRegistry::Status st = sqlLocal(stmt, NULL);
sqlHttp(stmt, NULL);
// status of local is only important one because asterisk talks to that db directly
// must update local no matter what
return st;
@ -458,6 +493,35 @@ SubscriberRegistry::Status SubscriberRegistry::RRLPUpdate(string name, string la
return sqlUpdate(os.str().c_str());
}
string SubscriberRegistry::getRandForAuthentication(bool sip, string IMSI)
{
if (IMSI.length() == 0) {
LOG(WARNING) << "SubscriberRegistry::getRandForAuthentication attempting lookup of NULL IMSI";
return "";
}
LOG(INFO) << "getRandForAuthentication(" << IMSI << ")";
// get rand from SR server
HttpQuery qry("rand");
qry.send("imsi", IMSI);
qry.log();
if (!qry.http(sip)) return "";
return qry.receive("rand");
}
bool SubscriberRegistry::getRandForAuthentication(bool sip, string IMSI, uint64_t *hRAND, uint64_t *lRAND)
{
string strRAND = getRandForAuthentication(sip, IMSI);
if (strRAND.length() == 0) {
*hRAND = 0;
*lRAND = 0;
return false;
}
stringToUint(strRAND, hRAND, lRAND);
return true;
}
void SubscriberRegistry::stringToUint(string strRAND, uint64_t *hRAND, uint64_t *lRAND)
{
assert(strRAND.size() == 32);
@ -495,6 +559,36 @@ string SubscriberRegistry::uintToString(uint32_t x)
return os.str();
}
SubscriberRegistry::Status SubscriberRegistry::authenticate(bool sip, string IMSI, uint64_t hRAND, uint64_t lRAND, uint32_t SRES)
{
string strRAND = uintToString(hRAND, lRAND);
string strSRES = uintToString(SRES);
return authenticate(sip, IMSI, strRAND, strSRES);
}
SubscriberRegistry::Status SubscriberRegistry::authenticate(bool sip, string IMSI, string rand, string sres)
{
if (IMSI.length() == 0) {
LOG(WARNING) << "SubscriberRegistry::authenticate attempting lookup of NULL IMSI";
return FAILURE;
}
LOG(INFO) << "authenticate(" << IMSI << "," << rand << "," << sres << ")";
HttpQuery qry("auth");
qry.send("imsi", IMSI);
qry.send("rand", rand);
qry.send("sres", sres);
qry.log();
if (!qry.http(sip)) return FAILURE;
const char *status = qry.receive("status");
if (strcmp(status, "SUCCESS") == 0) return SUCCESS;
if (strcmp(status, "FAILURE") == 0) return FAILURE;
// status is Kc
return SUCCESS;
}
bool SubscriberRegistry::useGateway(const char* ISDN)
{
// FIXME -- Do something more general in Asterisk.
@ -575,6 +669,122 @@ SubscriberRegistry::Status SubscriberRegistry::serviceUnits(const char *IMSI, co
HttpQuery::HttpQuery(const char *req)
{
sends = map<string,string>();
sends["req"] = req;
receives = map<string,string>();
}
void HttpQuery::send(const char *label, string value)
{
sends[label] = value;
}
void HttpQuery::log()
{
ostringstream os;
bool first = true;
for (map<string,string>::iterator it = sends.begin(); it != sends.end(); it++) {
if (first) {
first = false;
} else {
os << "&";
}
os << it->first << "=" << it->second;
}
LOG(INFO) << os.str();
}
bool HttpQuery::http(bool sip)
{
// unique temporary file names
ostringstream os1;
ostringstream os2;
os1 << "/tmp/subscriberregistry.1." << getpid();
os2 << "/tmp/subscriberregistry.2." << getpid();
string tmpFile1 = os1.str();
string tmpFile2 = os2.str();
// write the request and params to temp file
ofstream file1(tmpFile1.c_str());
if (file1.fail()) {
LOG(ERR) << "HttpQuery::http: can't write " << tmpFile1.c_str();
return false;
}
bool first = true;
for (map<string,string>::iterator it = sends.begin(); it != sends.end(); it++) {
if (first) {
first = false;
} else {
file1 << "&";
}
file1 << it->first << "=" << it->second;
}
file1.close();
// call the server
string server = sip ?
gConfig.getStr("SIP.Proxy.Registration"):
gConfig.getStr("SubscriberRegistry.UpstreamServer");
if (server.length() == 0 && !sip) return false;
ostringstream os;
os << "curl -s --data-binary @" << tmpFile1.c_str() << " " << server << " > " << tmpFile2.c_str();
LOG(INFO) << os.str();
if (server == "testing") {
return false;
} else {
int st = system(os.str().c_str());
if (st != 0) {
LOG(ERR) << "curl call returned " << st;
return false;
}
}
// read the http return from another temp file
ifstream file2(tmpFile2.c_str());
if (file2.fail()) {
LOG(ERR) << "HTTPQuery::http: can't read " << tmpFile2.c_str();
return false;
}
string tmp;
while (getline(file2, tmp)) {
size_t pos = tmp.find('=');
if (pos != string::npos) {
string key = tmp.substr(0, pos);
string value = tmp.substr(pos+1);
if (key == "error") {
LOG(ERR) << "HTTPQuery::http error: " << value;
file2.close();
return false;
}
receives[key] = value;
} else {
file2.close();
LOG(ERR) << "HTTPQuery::http: bad server return:";
ifstream file22(tmpFile2.c_str());
while (getline(file22, tmp)) {
LOG(ERR) << tmp;
}
file22.close();
return false;
}
}
file2.close();
return true;
}
const char *HttpQuery::receive(const char *label)
{
map<string,string>::iterator it = receives.find(label);
return it == receives.end() ? NULL : it->second.c_str();
}
// vim: ts=4 sw=4

View File

@ -42,7 +42,7 @@ class SubscriberRegistry {
private:
sqlite3 *mDB; ///< database connection
unsigned mNumSQLTries; ///< Number of times to try an sqlite command before giving up.
public:
@ -142,6 +142,24 @@ class SubscriberRegistry {
/**
Get a 128-bit number for authentication.
@param sip sip server (true) or http
@param IMSI The user's IMSI or SIP username.
@return the 128-bit number in hex
*/
string getRandForAuthentication(bool sip, string IMSI);
/**
Get a 128-bit number for authentication.
@param sip sip server (true) or http
@param IMSI The user's IMSI or SIP username;
@param hRAND upper 64 bits
@param lRAND lower 64 bits
*/
bool getRandForAuthentication(bool sip, string IMSI, uint64_t *hRAND, uint64_t *lRAND);
void stringToUint(string strRAND, uint64_t *hRAND, uint64_t *lRAND);
string uintToString(uint64_t h, uint64_t l);
@ -152,6 +170,18 @@ class SubscriberRegistry {
/**
Authenticate a handset.
@param sip sip server (true) or http
@param IMSI The user's IMSI or SIP username.
@param rand RAND.
@param sres SRES
@return ok or fail
*/
SubscriberRegistry::Status authenticate(bool sip, string IMSI, string rand, string sres);
bool useGateway(const char* ISDN);
@ -227,6 +257,15 @@ class SubscriberRegistry {
/**
Run sql statments over http.
@param stmt The sql statements.
@param resultptr Set this to point to the result of executing the statements.
*/
Status sqlHttp(const char *stmt, char **resultptr);
/**
Run an sql query (select unknownColumn from table where knownColumn = knownValue).
@param unknownColumn The column whose value you want.
@ -251,6 +290,74 @@ class SubscriberRegistry {
};
/** Class that SubscriberRegistry uses to setup an http query, run it, and get the results. */
class HttpQuery {
public:
/**
Constructor.
@param req The type of http query (sql, (get a)rand(om number) auth(enticate), etc).
*/
HttpQuery(const char *req);
/**
Specify a parameter to send in the http query.
@param label The label or name for the parameter.
@param value The value of the parameter.
*/
void send(const char *label, string value);
/**
Log the query.
*/
void log();
/**
This runs the http query.
@param sip Whether to call the sip server as opposed to the http server.
*/
bool http(bool sip);
/**
Get result from the http query.
@param label The label or name of the parameter whose value you want.
*/
const char *receive(const char *label);
private:
/** stores the parameters to send. */
map<string,string> sends;
/** stores the return parameters. */
map<string,string> receives;
};

270
comp128.c Normal file
View File

@ -0,0 +1,270 @@
/* An implementation of the GSM A3A8 algorithm. (Specifically, COMP128.)
*/
/* Copyright 1998, Marc Briceno, Ian Goldberg, and David Wagner.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of the authors nor the names of the contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Coded in C merely because C is a much more precise, concise form of
* expression for these purposes. See Judge Patel if you have any problems
* with this...
* Of course, it's only authentication, so it should be exportable for the
* usual boring reasons.
*/
typedef unsigned char Byte;
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
/* #define TEST */
/*
* rand[0..15]: the challenge from the base station
* key[0..15]: the SIM's A3/A8 long-term key Ki
* simoutput[0..11]: what you'd get back if you fed rand and key to a real
* SIM.
*
* The GSM spec states that simoutput[0..3] is SRES,
* and simoutput[4..11] is Kc (the A5 session key).
* (See GSM 11.11, Section 8.16. See also the leaked document
* referenced below.)
* Note that Kc is bits 74..127 of the COMP128 output, followed by 10
* zeros.
* In other words, A5 is keyed with only 54 bits of entropy. This
* represents a deliberate weakening of the key used for voice privacy
* by a factor of over 1000.
*
* Verified with a Pacific Bell Schlumberger SIM. Your mileage may vary.
*
* Marc Briceno <marc@scard.org>, Ian Goldberg <iang@cs.berkeley.edu>,
* and David Wagner <daw@cs.berkeley.edu>
*/
void A3A8(/* in */ Byte rand[16], /* in */ Byte key[16],
/* out */ Byte simoutput[12]);
/* The compression tables. */
static const Byte table_0[512] = {
102,177,186,162, 2,156,112, 75, 55, 25, 8, 12,251,193,246,188,
109,213,151, 53, 42, 79,191,115,233,242,164,223,209,148,108,161,
252, 37,244, 47, 64,211, 6,237,185,160,139,113, 76,138, 59, 70,
67, 26, 13,157, 63,179,221, 30,214, 36,166, 69,152,124,207,116,
247,194, 41, 84, 71, 1, 49, 14, 95, 35,169, 21, 96, 78,215,225,
182,243, 28, 92,201,118, 4, 74,248,128, 17, 11,146,132,245, 48,
149, 90,120, 39, 87,230,106,232,175, 19,126,190,202,141,137,176,
250, 27,101, 40,219,227, 58, 20, 51,178, 98,216,140, 22, 32,121,
61,103,203, 72, 29,110, 85,212,180,204,150,183, 15, 66,172,196,
56,197,158, 0,100, 45,153, 7,144,222,163,167, 60,135,210,231,
174,165, 38,249,224, 34,220,229,217,208,241, 68,206,189,125,255,
239, 54,168, 89,123,122, 73,145,117,234,143, 99,129,200,192, 82,
104,170,136,235, 93, 81,205,173,236, 94,105, 52, 46,228,198, 5,
57,254, 97,155,142,133,199,171,187, 50, 65,181,127,107,147,226,
184,218,131, 33, 77, 86, 31, 44, 88, 62,238, 18, 24, 43,154, 23,
80,159,134,111, 9,114, 3, 91, 16,130, 83, 10,195,240,253,119,
177,102,162,186,156, 2, 75,112, 25, 55, 12, 8,193,251,188,246,
213,109, 53,151, 79, 42,115,191,242,233,223,164,148,209,161,108,
37,252, 47,244,211, 64,237, 6,160,185,113,139,138, 76, 70, 59,
26, 67,157, 13,179, 63, 30,221, 36,214, 69,166,124,152,116,207,
194,247, 84, 41, 1, 71, 14, 49, 35, 95, 21,169, 78, 96,225,215,
243,182, 92, 28,118,201, 74, 4,128,248, 11, 17,132,146, 48,245,
90,149, 39,120,230, 87,232,106, 19,175,190,126,141,202,176,137,
27,250, 40,101,227,219, 20, 58,178, 51,216, 98, 22,140,121, 32,
103, 61, 72,203,110, 29,212, 85,204,180,183,150, 66, 15,196,172,
197, 56, 0,158, 45,100, 7,153,222,144,167,163,135, 60,231,210,
165,174,249, 38, 34,224,229,220,208,217, 68,241,189,206,255,125,
54,239, 89,168,122,123,145, 73,234,117, 99,143,200,129, 82,192,
170,104,235,136, 81, 93,173,205, 94,236, 52,105,228, 46, 5,198,
254, 57,155, 97,133,142,171,199, 50,187,181, 65,107,127,226,147,
218,184, 33,131, 86, 77, 44, 31, 62, 88, 18,238, 43, 24, 23,154,
159, 80,111,134,114, 9, 91, 3,130, 16, 10, 83,240,195,119,253
}, table_1[256] = {
19, 11, 80,114, 43, 1, 69, 94, 39, 18,127,117, 97, 3, 85, 43,
27,124, 70, 83, 47, 71, 63, 10, 47, 89, 79, 4, 14, 59, 11, 5,
35,107,103, 68, 21, 86, 36, 91, 85,126, 32, 50,109, 94,120, 6,
53, 79, 28, 45, 99, 95, 41, 34, 88, 68, 93, 55,110,125,105, 20,
90, 80, 76, 96, 23, 60, 89, 64,121, 56, 14, 74,101, 8, 19, 78,
76, 66,104, 46,111, 50, 32, 3, 39, 0, 58, 25, 92, 22, 18, 51,
57, 65,119,116, 22,109, 7, 86, 59, 93, 62,110, 78, 99, 77, 67,
12,113, 87, 98,102, 5, 88, 33, 38, 56, 23, 8, 75, 45, 13, 75,
95, 63, 28, 49,123,120, 20,112, 44, 30, 15, 98,106, 2,103, 29,
82,107, 42,124, 24, 30, 41, 16,108,100,117, 40, 73, 40, 7,114,
82,115, 36,112, 12,102,100, 84, 92, 48, 72, 97, 9, 54, 55, 74,
113,123, 17, 26, 53, 58, 4, 9, 69,122, 21,118, 42, 60, 27, 73,
118,125, 34, 15, 65,115, 84, 64, 62, 81, 70, 1, 24,111,121, 83,
104, 81, 49,127, 48,105, 31, 10, 6, 91, 87, 37, 16, 54,116,126,
31, 38, 13, 0, 72,106, 77, 61, 26, 67, 46, 29, 96, 37, 61, 52,
101, 17, 44,108, 71, 52, 66, 57, 33, 51, 25, 90, 2,119,122, 35
}, table_2[128] = {
52, 50, 44, 6, 21, 49, 41, 59, 39, 51, 25, 32, 51, 47, 52, 43,
37, 4, 40, 34, 61, 12, 28, 4, 58, 23, 8, 15, 12, 22, 9, 18,
55, 10, 33, 35, 50, 1, 43, 3, 57, 13, 62, 14, 7, 42, 44, 59,
62, 57, 27, 6, 8, 31, 26, 54, 41, 22, 45, 20, 39, 3, 16, 56,
48, 2, 21, 28, 36, 42, 60, 33, 34, 18, 0, 11, 24, 10, 17, 61,
29, 14, 45, 26, 55, 46, 11, 17, 54, 46, 9, 24, 30, 60, 32, 0,
20, 38, 2, 30, 58, 35, 1, 16, 56, 40, 23, 48, 13, 19, 19, 27,
31, 53, 47, 38, 63, 15, 49, 5, 37, 53, 25, 36, 63, 29, 5, 7
}, table_3[64] = {
1, 5, 29, 6, 25, 1, 18, 23, 17, 19, 0, 9, 24, 25, 6, 31,
28, 20, 24, 30, 4, 27, 3, 13, 15, 16, 14, 18, 4, 3, 8, 9,
20, 0, 12, 26, 21, 8, 28, 2, 29, 2, 15, 7, 11, 22, 14, 10,
17, 21, 12, 30, 26, 27, 16, 31, 11, 7, 13, 23, 10, 5, 22, 19
}, table_4[32] = {
15, 12, 10, 4, 1, 14, 11, 7, 5, 0, 14, 7, 1, 2, 13, 8,
10, 3, 4, 9, 6, 0, 3, 2, 5, 6, 8, 9, 11, 13, 15, 12
}, *table[5] = { table_0, table_1, table_2, table_3, table_4 };
/*
* This code derived from a leaked document from the GSM standards.
* Some missing pieces were filled in by reverse-engineering a working SIM.
* We have verified that this is the correct COMP128 algorithm.
*
* The first page of the document identifies it as
* _Technical Information: GSM System Security Study_.
* 10-1617-01, 10th June 1988.
* The bottom of the title page is marked
* Racal Research Ltd.
* Worton Drive, Worton Grange Industrial Estate,
* Reading, Berks. RG2 0SB, England.
* Telephone: Reading (0734) 868601 Telex: 847152
* The relevant bits are in Part I, Section 20 (pages 66--67). Enjoy!
*
* Note: There are three typos in the spec (discovered by
* reverse-engineering).
* First, "z = (2 * x[n] + x[n]) mod 2^(9-j)" should clearly read
* "z = (2 * x[m] + x[n]) mod 2^(9-j)".
* Second, the "k" loop in the "Form bits from bytes" section is severely
* botched: the k index should run only from 0 to 3, and clearly the range
* on "the (8-k)th bit of byte j" is also off (should be 0..7, not 1..8,
* to be consistent with the subsequent section).
* Third, SRES is taken from the first 8 nibbles of x[], not the last 8 as
* claimed in the document. (And the document doesn't specify how Kc is
* derived, but that was also easily discovered with reverse engineering.)
* All of these typos have been corrected in the following code.
*/
void A3A8(/* in */ Byte rand[16], /* in */ Byte key[16],
/* out */ Byte simoutput[12])
{
Byte x[32], bit[128];
int i, j, k, l, m, n, y, z, next_bit;
/* ( Load RAND into last 16 bytes of input ) */
for (i=16; i<32; i++)
x[i] = rand[i-16];
/* ( Loop eight times ) */
for (i=1; i<9; i++) {
/* ( Load key into first 16 bytes of input ) */
for (j=0; j<16; j++)
x[j] = key[j];
/* ( Perform substitutions ) */
for (j=0; j<5; j++)
for (k=0; k<(1<<j); k++)
for (l=0; l<(1<<(4-j)); l++) {
m = l + k*(1<<(5-j));
n = m + (1<<(4-j));
y = (x[m]+2*x[n]) % (1<<(9-j));
z = (2*x[m]+x[n]) % (1<<(9-j));
x[m] = table[j][y];
x[n] = table[j][z];
}
/* ( Form bits from bytes ) */
for (j=0; j<32; j++)
for (k=0; k<4; k++)
bit[4*j+k] = (x[j]>>(3-k)) & 1;
/* ( Permutation but not on the last loop ) */
if (i < 8)
for (j=0; j<16; j++) {
x[j+16] = 0;
for (k=0; k<8; k++) {
next_bit = ((8*j + k)*17) % 128;
x[j+16] |= bit[next_bit] << (7-k);
}
}
}
/*
* ( At this stage the vector x[] consists of 32 nibbles.
* The first 8 of these are taken as the output SRES. )
*/
/* The remainder of the code is not given explicitly in the
* standard, but was derived by reverse-engineering.
*/
for (i=0; i<4; i++)
simoutput[i] = (x[2*i]<<4) | x[2*i+1];
for (i=0; i<6; i++)
simoutput[4+i] = (x[2*i+18]<<6) | (x[2*i+18+1]<<2)
| (x[2*i+18+2]>>2);
simoutput[4+6] = (x[2*6+18]<<6) | (x[2*6+18+1]<<2);
simoutput[4+7] = 0;
}
int hextoint(char x)
{
x = toupper(x);
if (x >= 'A' && x <= 'F')
return x-'A'+10;
else if (x >= '0' && x <= '9')
return x-'0';
fprintf(stderr, "bad input.\n");
exit(1);
}
int main(int argc, char **argv)
{
Byte key[16], rand[16], simoutput[12];
int i;
if (argc != 3 || strlen(argv[1]) != 34 || strlen(argv[2]) != 34
|| strncmp(argv[1], "0x", 2) != 0
|| strncmp(argv[2], "0x", 2) != 0) {
fprintf(stderr, "Usage: %s 0x<32-digit-key> 0x<32-digit-rand>\n", argv[0]);
printf("error\n");
exit(1);
}
for (i=0; i<16; i++)
key[i] = (hextoint(argv[1][2*i+2])<<4)
| hextoint(argv[1][2*i+3]);
for (i=0; i<16; i++)
rand[i] = (hextoint(argv[2][2*i+2])<<4)
| hextoint(argv[2][2*i+3]);
A3A8(rand, key, simoutput);
for (i=0; i<12; i++)
printf("%02X", simoutput[i]);
printf("\n");
return 0;
}

View File

@ -69,7 +69,7 @@
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION "2.8TRUNK"
#define PACKAGE_VERSION "3.0TRUNK"
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
@ -78,7 +78,7 @@
#define TIME_WITH_SYS_TIME 1
/* Version number of package */
#define VERSION "2.8TRUNK"
#define VERSION "3.0TRUNK"
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
significant byte first (like Motorola and SPARC, unlike Intel). */

9
debian/changelog vendored
View File

@ -1,10 +1,11 @@
sipauthserve-public (2.8) precise; urgency=low
sipauthserve-public (3.2) UNRELEASED; urgency=low
* Initial release of public debian packaging scripts
* Non-maintainer upload.
* Public release
-- Kurtis Heimerl <kheimerl@darth-tyranus> Sat, 06 Jul 2013 21:17:23 -0700
-- Kurtis <kheimerl@rangenetworks.com> Tue, 30 Jul 2013 23:01:28 -0700
sipauthserve-public (2.8) UNRELEASED; urgency=low
sipauthserve-public (3.2) UNRELEASED; urgency=low
* Test

11
debian/control vendored
View File

@ -1,18 +1,19 @@
Source: sipauthserve-public
Provides: sipauthserve
Section: comm
Priority: optional
Maintainer: Range Networks, Inc. <info@rangenetworks.com>
Homepage: http://www.rangenetworks.com/
Build-Depends: build-essential, debhelper (>= 7), libosip2-dev, pkg-config, autoconf
Build-Depends: build-essential, debhelper (>= 7), libosip2-dev, pkg-config, autoconf, libsqlite3-dev (>= 3.7)
Standards-Version: 3.7.3
Package: sipauthserve-public
Version: P2.8TRUNK
Provides: sipauthserve
Version: TRUNK
Section: comm
Priority: optional
Architecture: any
Essential: no
Depends: sqlite3, libosip2-4, libglib2.0-0, libgl1-mesa-glx, libc6, libasound2, pkg-config, libpcre3, gawk
Conflicts: sipauthserve
Description: Sipauthserver, the authorization server for OpenBTS.
Depends: sqlite, sqlite3 (>= 3.7), libosip2-4, libglib2.0-0, libgl1-mesa-glx, libc6, libasound2, pkg-config, libpcre3, gawk, screen
Description: OpenBTS Public software.

18
debian/postinst vendored
View File

@ -23,13 +23,11 @@ DB_LOC=/etc/OpenBTS/sipauthserve.db
DATE=$(date +'%Y-%m-%d.%H:%M:%S')
CONFIG_BACKUP=$DB_LOC.dump-$DATE
if [ -e $DB_LOC ]; then
if [ ! -e $CONFIG_BACKUP ]; then
sqlite3 $DB_LOC ".dump" > $CONFIG_BACKUP
fi
#create the SR config db
sqlite3 $DB_LOC ".read /etc/OpenBTS/sipauthserve.example.sql" > /dev/null 2>&1
sqlite3 $DB_LOC ".read /etc/OpenBTS/subscriberRegistry.example.sql" > /dev/null 2>&1
SR_DIR=/var/lib/asterisk/sqlite3dir
SRPATH=$SR_DIR/sqlite3.db
@ -41,8 +39,6 @@ fi
chown -R root:www-data $SR_DIR
chmod 775 $SR_DIR
sqlite3 $SRPATH ".read /etc/OpenBTS/subscriberRegistryInit.sql" > /dev/null 2>&1
if [ -e $SRPATH ]; then
if [ ! -e $SR_CONFIG_BACKUP ]; then
sqlite3 $SRPATH ".dump" > $SR_CONFIG_BACKUP
@ -58,12 +54,14 @@ if [ -e $SRPATH ]; then
sqlite3 $SRPATH "alter table sip_buddies add column account_balance int(9) default 0"
fi
sqlite3 $SRPATH "insert or ignore into 'rates' values ('in-network-SMS', 0)"
sqlite3 $SRPATH "insert or ignore into 'rates' values ('out-of-network-SMS', 0)"
sqlite3 $SRPATH "insert or ignore into 'rates' values ('in-network-call', 0)"
sqlite3 $SRPATH "insert or ignore into 'rates' values ('out-of-network-call', 0)"
sqlite3 $SRPATH "create table if not exists rates (service varchar(30) unique not null, rate integer not null)"
sqlite3 $SRPATH "insert or ignore into 'rates' values ('in-network-SMS', 10)"
sqlite3 $SRPATH "insert or ignore into 'rates' values ('out-of-network-SMS', 20)"
sqlite3 $SRPATH "insert or ignore into 'rates' values ('in-network-call', 1)"
sqlite3 $SRPATH "insert or ignore into 'rates' values ('out-of-network-call', 1)"
fi
# set up permissions for webui, temporary fix until ui is replumbed to use json
# directory permissions
if [ -e $SRPATH ]; then

6
debian/prerm vendored
View File

@ -20,11 +20,7 @@ APP=sipauthserve
remove()
{
if [ "$(pidof $APP)" ]; then
killall $APP
else
echo "$APP not running"
fi
killall $APP &>/dev/null
}
case "$1" in

View File

@ -1,4 +0,0 @@
#!/bin/sh
# A script to restart and just keep sipauthserve running.
while true; do killall sipauthserve; sleep 2; ./sipauthserve; done

View File

@ -46,11 +46,100 @@ extern SubscriberRegistry gSubscriberRegistry;
ConfigurationKeyMap getConfigurationKeys()
{
ConfigurationKeyMap map;
ConfigurationKey *tmp;
tmp = new ConfigurationKey("SIP.Proxy.Registration","127.0.0.1:5064",
"",
ConfigurationKey::CUSTOMERWARN,
ConfigurationKey::IPANDPORT,
"",
false,
"The IP host and port of the proxy to be used for registration and authentication. "
"This should normally be the subscriber registry SIP interface, not Asterisk."
);
map[tmp->getName()] = *tmp;
delete tmp;
tmp = new ConfigurationKey("SubscriberRegistry.A3A8","/OpenBTS/comp128",
"",
ConfigurationKey::CUSTOMERWARN,
ConfigurationKey::FILEPATH,
"",
false,
"Path to the program that implements the A3/A8 algorithm."
);
map[tmp->getName()] = *tmp;
delete tmp;
tmp = new ConfigurationKey("SubscriberRegistry.db","/var/lib/asterisk/sqlite3dir/sqlite3.db",
"",
ConfigurationKey::CUSTOMERWARN,
ConfigurationKey::FILEPATH,
"",
false,
"The location of the sqlite3 database holding the subscriber registry."
);
map[tmp->getName()] = *tmp;
delete tmp;
tmp = new ConfigurationKey("SubscriberRegistry.Manager.Title","Subscriber Registry",
"",
ConfigurationKey::CUSTOMER,
ConfigurationKey::STRING,
"^[[:print:]]+$",
false,
"Title text to be displayed on the subscriber registry manager."
);
map[tmp->getName()] = *tmp;
delete tmp;
tmp = new ConfigurationKey("SubscriberRegistry.Manager.VisibleColumns","name username type context host",
"",
ConfigurationKey::CUSTOMERTUNE,
ConfigurationKey::STRING,
"^(name){0,1} (username){0,1} (type){0,1} (context){0,1} (host){0,1}$",
false,
"A space separated list of columns to display in the subscriber registry manager."
);
map[tmp->getName()] = *tmp;
delete tmp;
tmp = new ConfigurationKey("SubscriberRegistry.Port","5064",
"",
ConfigurationKey::CUSTOMERWARN,
ConfigurationKey::PORT,
"",
false,
"Port used by the SIP Authentication Server. NOTE: In some older releases (pre-2.8.1) this is called SIP.myPort."
);
map[tmp->getName()] = *tmp;
delete tmp;
tmp = new ConfigurationKey("SubscriberRegistry.UpstreamServer","",
"",
ConfigurationKey::CUSTOMERWARN,
ConfigurationKey::STRING_OPT,// audited
"",
false,
"URL of the subscriber registry HTTP interface on the upstream server. "
"By default, this feature is disabled. "
"To enable, specify a server URL eg: http://localhost/cgi/subreg.cgi. "
"To disable again, execute \"unconfig SubscriberRegistry.UpstreamServer\"."
);
map[tmp->getName()] = *tmp;
delete tmp;
return map;
}
string imsiGet(string imsi, string key)
{
string name = imsi.substr(0,4) == "IMSI" ? imsi : "IMSI" + imsi;
char *value;
if (!sqlite3_single_lookup(gSubscriberRegistry.db(), "sip_buddies", "name", name.c_str(), key.c_str(), value)) {
if (!sqlite3_single_lookup(gSubscriberRegistry.db(), "sip_buddies", "username", name.c_str(), key.c_str(), value)) {
return "";
}
if (!value) { return ""; }
@ -63,7 +152,7 @@ void imsiSet(string imsi, string key, string value)
{
string name = imsi.substr(0,4) == "IMSI" ? imsi : "IMSI" + imsi;
ostringstream os2;
os2 << "update sip_buddies set " << key << " = \"" << value << "\" where name = \"" << name << "\"";
os2 << "update sip_buddies set " << key << " = \"" << value << "\" where username = \"" << name << "\"";
if (!sqlite3_command(gSubscriberRegistry.db(), os2.str().c_str())) {
LOG(ERR) << "sqlite3_command problem";
return;
@ -116,6 +205,121 @@ bool strEqual(string a, string b)
return 0 == strcasecmp(a.c_str(), b.c_str());
}
bool sresEqual(string a, string b)
{
stringstream ss1;
stringstream ss2;
uint32_t sres1 = 0xffffffff;
uint32_t sres2 = 0xffffffff;
if (a.empty() || b.empty())
return false;
ss1 << hex << a;
ss2 << hex << b;
ss1 >> sres1;
ss2 >> sres2;
LOG(DEBUG) << "sres1 = " << sres1;
LOG(DEBUG) << "sres2 = " << sres2;
return (sres1 == sres2);
}
bool randEqual(string a, string b)
{
uint64_t rand1h = 0;
uint64_t rand1l = 0;
uint64_t rand2h = 0;
uint64_t rand2l = 0;
if (a.empty() || b.empty())
return false;
gSubscriberRegistry.stringToUint(a, &rand1h, &rand1l);
gSubscriberRegistry.stringToUint(b, &rand2h, &rand2l);
LOG(DEBUG) << "rand1h = " << rand1h << ", rand1l = " << rand1l;
LOG(DEBUG) << "rand2h = " << rand2h << ", rand2l = " << rand2l;
return (rand1h == rand2h) && (rand1l == rand2l);
}
// verify sres given rand and imsi's ki
// may set kc
// may cache sres and rand
bool authenticate(string imsi, string randx, string sres, string *kc)
{
string ki = imsiGet(imsi, "ki");
bool ret;
if (ki.length() == 0) {
// Ki is unknown
string upstream_server = gConfig.getStr("SubscriberRegistry.UpstreamServer");
if (upstream_server.length()) {
LOG(INFO) << "ki unknown, upstream server";
// there's an upstream server for authentication.
// TODO - call the upstream server
ret = false;
} else {
// there's no upstream server for authentication. fake it.
string sres2 = imsiGet(imsi, "sres");
if (sres2.length() == 0) {
LOG(INFO) << "ki unknown, no upstream server, sres not cached";
// first time - cache sres and rand so next time
// correct cell phone will calc same sres from same rand
imsiSet(imsi, "sres", sres);
imsiSet(imsi, "rand", randx);
ret = true;
} else {
LOG(INFO) << "ki unknown, no upstream server, sres cached";
// check against cached values of rand and sres
string rand2 = imsiGet(imsi, "rand");
// TODO - on success, compute and return kc
LOG(DEBUG) << "comparing " << sres << " to " << sres2 << " and " << randx << " to " << rand2;
ret = sresEqual(sres, sres2) && randEqual(randx, rand2);
}
}
} else {
LOG(INFO) << "ki known";
// Ki is known, so do normal authentication
ostringstream os;
// per user value from subscriber registry
string a3a8 = imsiGet(imsi, "a3_a8");
if (a3a8.length() == 0) {
// config value is default
a3a8 = gConfig.getStr("SubscriberRegistry.A3A8");
}
os << a3a8 << " 0x" << ki << " 0x" << randx;
// must not put ki into the log
// LOG(INFO) << "running " << os.str();
FILE *f = popen(os.str().c_str(), "r");
if (f == NULL) {
LOG(CRIT) << "error: popen failed";
return false;
}
char sres2[26];
char *str = fgets(sres2, 26, f);
if (str != NULL && strlen(str) == 25) str[24] = 0;
if (str == NULL || strlen(str) != 24) {
LOG(CRIT) << "error: popen result failed";
return false;
}
int st = pclose(f);
if (st == -1) {
LOG(CRIT) << "error: pclose failed";
return false;
}
// first 8 chars are SRES; rest are Kc
*kc = sres2+8;
sres2[8] = 0;
LOG(INFO) << "result = " << sres2;
ret = sresEqual(sres, sres2);
}
LOG(INFO) << "returning = " << ret;
return ret;
}
void decodeQuery(map<string,string> &args)
{
string query;

View File

@ -29,6 +29,11 @@
using namespace std;
/**
Returns all valid configuration keys for the subscriber registry.
*/
ConfigurationKeyMap getConfigurationKeys();
/**
Get a subscriber's property.
@param imsi imsi of the subscriber
@ -50,6 +55,14 @@ void imsiSet(string imsi, string key, string value);
*/
string generateRand(string imsi);
/**
Authenticate
@param imsi imsi of subscriber
@param rand random number
@param sres corresponsing sres
*/
bool authenticate(string imsi, string rand, string sres, string *kc);
/**
Decode the html query.
@param args mapping of query key->value pairs.

View File

@ -1,27 +0,0 @@
#!/bin/sh
# Install subscriber registry and assocated files.
if [ "$USER" != "root" ]; then
echo This script must be run as super-user.
exit 1
fi
IPATH=/usr/local/bin
cp comp128 $IPATH
cp hexmapper $IPATH
cp syslogextractor $IPATH
CGIPATH=/var/cgi-bin
cp srmanager.cgi $CGIPATH
cp subscriberserver.cgi $CGIPATH
cp comp128 /OpenBTS
cp sipauthserve /OpenBTS
cp runloop.sipauthserve.sh /OpenBTS
# Don't do this. This will be created when the SR starts running.
#DBPATH=/var/lib/asterisk/sqlite3dir
#sqlite3 $DBPATH/sqlite3.db ".read configFiles/subscriberRegistryInit.sql"
#cp configFiles/subscriberRegistryInit.sql $DBPATH

View File

@ -50,7 +50,8 @@
using namespace std;
ConfigurationTable gConfig("/etc/OpenBTS/sipauthserve.db");
ConfigurationTable gConfig("/etc/OpenBTS/sipauthserve.db", "sipauthserve", getConfigurationKeys());
Log dummy("sipauthserve", gConfig.getStr("Log.Level").c_str(), LOG_LOCAL7);
int my_udp_port;
@ -175,14 +176,79 @@ char *processBuffer(char *buffer)
// imsi problem => 404 IMSI Not Found
osip_message_set_status_code (response, 404);
osip_message_set_reason_phrase (response, osip_strdup("IMSI Not Found"));
} else {
// sres matches rand => 200 OK
osip_message_set_status_code (response, 200);
osip_message_set_reason_phrase (response, osip_strdup("OK"));
// And register it.
LOG(INFO) << "success, registering for IP address " << remote_host << ":" << remote_port;
imsiSet(imsi,"ipaddr",remote_host);
} else if (gConfig.defines("SubscriberRegistry.IgnoreAuthentication")) {
osip_message_set_status_code (response, 200);
osip_message_set_reason_phrase (response, osip_strdup("OK"));
LOG(INFO) << "success, registering for IP address " << remote_host;
imsiSet(imsi,"ipaddr",remote_host);
imsiSet(imsi,"port",remote_port);
} else {
// look for rand and sres in Authorization header (assume imsi same as in from)
string randx;
string sres;
// sip parser is not working reliably for Authorization, so we'll do the parsing
char *RAND = strcasestr(buffer, "nonce=");
char *SRES = strcasestr(buffer, "response=");
if (RAND && SRES) {
// find RAND digits
RAND += 6;
while (!isalnum(*RAND)) { RAND++; }
RAND[32] = 0;
int j=0;
// FIXME -- These loops should use strspn instead.
while(isalnum(RAND[j])) { j++; }
RAND[j] = '\0';
// find SRES digits
SRES += 9;
while (!isalnum(*SRES)) { SRES++; }
int i=0;
// FIXME -- These loops should use strspn instead.
while(isalnum(SRES[i])) { i++; }
SRES[i] = '\0';
LOG(INFO) << "rand = /" << RAND << "/";
LOG(INFO) << "sres = /" << SRES << "/";
}
if (!RAND || !SRES) {
LOG(NOTICE) << "imsi known, 1st register";
// no rand and sres => 401 Unauthorized
osip_message_set_status_code (response, 401);
osip_message_set_reason_phrase (response, osip_strdup("Unauthorized"));
// but include rand in www_authenticate
osip_www_authenticate_t *auth;
osip_www_authenticate_init(&auth);
// auth type is required by osip_www_authenticate_to_str (and therefore osip_message_to_str)
string auth_type = "Digest";
osip_www_authenticate_set_auth_type(auth, osip_strdup(auth_type.c_str()));
// returning RAND in www_authenticate header
string randz = generateRand(imsi);
osip_www_authenticate_set_nonce(auth, osip_strdup(randz.c_str()));
i = osip_list_add (&response->www_authenticates, auth, -1);
if (i < 0) LOG(ERR) << "problem adding www_authenticate";
} else {
string kc;
bool sres_good = authenticate(imsi, RAND, SRES, &kc);
LOG(INFO) << "imsi known, 2nd register, good = " << sres_good;
if (sres_good) {
// sres matches rand => 200 OK
osip_message_set_status_code (response, 200);
osip_message_set_reason_phrase (response, osip_strdup("OK"));
if (kc.size() != 0) {
osip_authentication_info *auth;
osip_authentication_info_init(&auth);
osip_authentication_info_set_cnonce(auth, osip_strdup(kc.c_str()));
i = osip_list_add (&response->authentication_infos, auth, -1);
if (i < 0) LOG(ERR) << "problem adding authentication_infos";
}
// And register it.
LOG(INFO) << "success, registering for IP address " << remote_host;
imsiSet(imsi,"ipaddr",remote_host);
imsiSet(imsi,"port",remote_port);
} else {
// sres does not match rand => 401 Unauthorized
osip_message_set_status_code (response, 401);
osip_message_set_reason_phrase (response, osip_strdup("Unauthorized"));
}
}
}
prettyPrint("response", response);
@ -210,7 +276,6 @@ main(int argc, char **argv)
int aSocket;
char buf[BUFLEN];
gLogInit("sipauthserve", gConfig.getStr("Log.Level").c_str(), LOG_LOCAL7);
LOG(ALERT) << argv[0] << " (re)starting";
srand ( time(NULL) + (int)getpid() );
my_udp_port = gConfig.getNum("SubscriberRegistry.Port");

View File

@ -39,7 +39,8 @@
using namespace std;
ConfigurationTable gConfig("/etc/OpenBTS/sipauthserve.db");
ConfigurationTable gConfig("/etc/OpenBTS/OpenBTS.db", "srmanager", getConfigurationKeys());
Log dummy("srmanager",gConfig.getStr("Log.Level").c_str(),LOG_LOCAL7);
map<string,string> gArgs;
string gDatabase;
string gVisibleSipColumns;
@ -86,13 +87,14 @@ void initTable(vector<string> &cols)
void table(const char *tableName, vector<string> &cols, bool addButtonP, const char *note)
{
cout << "<h4>" << gDatabase << "." << tableName << " (" << note << ")</h4>\n";
cout << "<h4>" << gDatabase << "." << tableName << " " << note << "</h4>\n";
initTable(cols);
ostringstream os;
os << "select id," << join(",", cols) << " from " << tableName;
sqlite3_stmt *stmt;
if (sqlite3_prepare_statement(gSubscriberRegistry.db(), &stmt,os.str().c_str())) {
cout << "sqlite3_prepare_statement problem" << endl;
LOG(ERR) << "sqlite3_prepare_statement problem - statement: " << os.str();
LOG(ERR) << " " << sqlite3_errmsg(gSubscriberRegistry.db());
return;
}
int src = sqlite3_run_query(gSubscriberRegistry.db(), stmt);
@ -101,7 +103,7 @@ void table(const char *tableName, vector<string> &cols, bool addButtonP, const c
const char *id = (const char*)sqlite3_column_text(stmt, 0);
for (int i = 1; i <= (int)cols.size(); i++) {
const char *value = (const char*)sqlite3_column_text(stmt, i);
values.push_back(value ? value : "-NULL-");
values.push_back(value ? value : "(null)");
}
tableRow(cols, values, UPDATE_BUTTON | DELETE_BUTTON, id);
src = sqlite3_run_query(gSubscriberRegistry.db(), stmt);
@ -121,6 +123,7 @@ void getFields(vector<string> *fields, vector<bool> *isSet)
const char *cmd = "pragma table_info(sip_buddies)";
if (sqlite3_prepare_statement(gSubscriberRegistry.db(), &stmt, cmd)) {
LOG(ERR) << "sqlite3_prepare_statement problem - statement: " << cmd;
LOG(ERR) << " " << sqlite3_errmsg(gSubscriberRegistry.db());
return;
}
int src = sqlite3_run_query(gSubscriberRegistry.db(), stmt);
@ -146,7 +149,7 @@ void mainTables()
vector<string> vsc;
split(' ', gVisibleSipColumns, &vsc);
table("sip_buddies", vsc, false, "scroll down to change which fields of sip_buddies are visible");
table("sip_buddies", vsc, false, "(scroll down to change which fields of sip_buddies are visible)");
cout << "<hr>";
vector<string> vec;
split(' ', gVisibleExtColumns, &vec);
@ -170,6 +173,15 @@ void mainTables()
cout << "</form>\n";
}
string nullCheck(string s)
{
if (s == "(null)") {
return "NULL";
} else {
return "\"" + s + "\"";
}
}
void doCmd(string cmd)
{
string table;
@ -188,7 +200,7 @@ void doCmd(string cmd)
vector<string> values0;
vector<string>::iterator it;
for (it = cols.begin(); it != cols.end(); it++) {
values0.push_back("\"" + gArgs[*it] + "\"");
values0.push_back(nullCheck(gArgs[*it]));
}
string values = join(",", values0);
os << "insert into " << table << " (" << names << ") values (" << values << ")";
@ -198,15 +210,16 @@ void doCmd(string cmd)
vector<string> sets0;
vector<string>::iterator it;
for (it = cols.begin(); it != cols.end(); it++) {
sets0.push_back(*it + "=\"" + gArgs[*it] + "\"");
sets0.push_back(*it + "=" + nullCheck(gArgs[*it]));
}
string sets = join(",", sets0);
os << "update " << table << " set " << sets << " where id = " << id;
} else {
cout << "internal error<br>\n";
LOG(ERR) << "internal error";
}
LOG(INFO) << os.str();
if (!sqlite3_command(gSubscriberRegistry.db(), os.str().c_str())) {
cout << "sqlite3_command problem" << endl;
LOG(ERR) << "sqlite3_command problem - statement: " << os.str();
return;
}
mainTables();
@ -234,16 +247,34 @@ void endHtml()
cout << "</HTML>\n";
}
void doVisibles()
{
gVisibleSipColumns = "";
map<string,string>::iterator it;
bool first = true;
for (it = gArgs.begin(); it != gArgs.end(); it++) {
if (it->first == "what") continue;
if (first) {
first = false;
} else {
gVisibleSipColumns += " ";
}
gVisibleSipColumns += it->first;
}
if (!gConfig.set("SubscriberRegistry.Manager.VisibleColumns", gVisibleSipColumns)) {
LOG(ERR) << "unable to update SubscriberRegistry.Manager.VisibleColumns";
}
}
int main(int argc, char **argv)
{
gLogInit("srmanager",gConfig.getStr("Log.Level").c_str(),LOG_LOCAL7);
gSubscriberRegistry.init();
// read the config file
gVisibleSipColumns = gConfig.getStr("SubscriberRegistry.Manager.VisibleColumns");
gUrl = argv[0];
gTitle = gConfig.getStr("SubscriberRegistry.Manager.Title");
// start the html return
initHtml();
// read the config file
gVisibleSipColumns = gConfig.getStr("SubscriberRegistry.Manager.VisibleColumns");
gUrl = "/cgi/srmanager.cgi";
gTitle = gConfig.getStr("SubscriberRegistry.Manager.Title");
// connect to the database
gDatabase = gConfig.getStr("SubscriberRegistry.db");
// decode the http query
@ -262,21 +293,7 @@ int main(int argc, char **argv)
gSubscriberRegistry.addUser(gArgs["imsi"].c_str(), gArgs["phonenumber"].c_str());
mainTables();
} else if (what == "Submit") {
gVisibleSipColumns = "";
map<string,string>::iterator it;
bool first = true;
for (it = gArgs.begin(); it != gArgs.end(); it++) {
if (it->first == "what") continue;
if (first) {
first = false;
} else {
gVisibleSipColumns += " ";
}
gVisibleSipColumns += it->first;
}
if (!gConfig.set("SubscriberRegistry.Manager.VisibleColumns", gVisibleSipColumns)) {
LOG(ERR) << "unable to update SubscriberRegistry.Manager.VisibleColumns";
}
doVisibles();
mainTables();
} else {
cout << "unrecognized what parameter<br>\n";

View File

@ -0,0 +1,11 @@
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE IF NOT EXISTS CONFIG ( KEYSTRING TEXT UNIQUE NOT NULL, VALUESTRING TEXT, STATIC INTEGER DEFAULT 0, OPTIONAL INTEGER DEFAULT 0, COMMENTS TEXT DEFAULT '');
INSERT OR IGNORE INTO "CONFIG" VALUES('SubscriberRegistry.A3A8','./comp128',0,0,'Path to the program that implements the A3/A8 algorithm.');
INSERT OR IGNORE INTO "CONFIG" VALUES('SubscriberRegistry.Manager.Title','Subscriber Registry',0,0,'Title text to be displayed on the subscriber registry manager.');
INSERT OR IGNORE INTO "CONFIG" VALUES('SubscriberRegistry.Port','5064',0,0,'Port used by the SIP Authentication Server. NOTE: In some older releases (pre-2.8.1) this is called SIP.myPort.');
INSERT OR IGNORE INTO "CONFIG" VALUES('SubscriberRegistry.UpstreamServer','',0,0,'URL of the subscriber registry HTTP interface on the upstream server. By default, this feature is disabled. To enable, specify a server URL eg: http://localhost/cgi/subreg.cgi. To disable again, execute "unconfig SubscriberRegistry.UpstreamServer".');
INSERT OR IGNORE INTO "CONFIG" VALUES('SubscriberRegistry.db','/var/lib/asterisk/sqlite3dir/sqlite3.db',0,0,'The location of the sqlite3 database holding the subscriber registry.');
COMMIT;

193
subscriberserver.cpp Executable file
View File

@ -0,0 +1,193 @@
/*
* Copyright 2011 Kestrel Signal Processing, Inc.
* Copyright 2011 Range Networks, Inc.
*
* This software is distributed under the terms of the GNU Affero Public License.
* See the COPYING file in the main directory for details.
*
* This use of this software may be subject to additional restrictions.
* See the LEGAL file in the main directory for details.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <iostream>
#include <sstream>
#include <fstream>
#include <map>
#include <vector>
#include <string>
#include <sqlite3.h>
#include <time.h>
#include "Configuration.h"
#include "Logger.h"
#include <string.h>
#include "servershare.h"
#include "SubscriberRegistry.h"
using namespace std;
ConfigurationTable gConfig("/etc/OpenBTS/OpenBTS.db", "subscriberserver", getConfigurationKeys());
Log dummy("subscriberserver",gConfig.getStr("Log.Level").c_str(),LOG_LOCAL7);
// just using this for the database access
SubscriberRegistry gSubscriberRegistry;
// map of http query parameters and values
map<string,string> gArgs;
// lines of http response
vector<string> gResponse;
// retrieve a query field from args
string getArg(string label)
{
if (gArgs.find(label) == gArgs.end()) {
LOG(ERR) << "error: " << label << " missing";
return "";
}
return gArgs[label];
}
// run an sql statement through sqlite3 to get a response
void generateSqlResponse()
{
string stmts = getArg("stmts");
vector<string> vstmts;
split(';', stmts, &vstmts);
vector<string>::iterator it;
for (it = vstmts.begin(); it != vstmts.end(); it++) {
sqlite3_stmt *stmt;
if (sqlite3_prepare_statement(gSubscriberRegistry.db(), &stmt, it->c_str())) {
LOG(ERR) << "sqlite3_prepare_statement problem - statement: " << it->c_str();
return;
}
int src = sqlite3_run_query(gSubscriberRegistry.db(), stmt);
while (src == SQLITE_ROW) {
string resp = "res=";
int cols = sqlite3_column_count(stmt);
for (int i = 0; i < cols; i++) {
resp.append((const char*)sqlite3_column_text(stmt, i));
}
gResponse.push_back(resp);
src = sqlite3_run_query(gSubscriberRegistry.db(), stmt);
}
}
}
void sresCheck(bool b)
{
if (b) {
// SRESs match. return success (or Kc (TODO))
gResponse.push_back("status=SUCCESS");
} else {
// SRESs don't match. return failure.
gResponse.push_back("status=FAILURE");
}
}
// authenticate
void generateAuthResponse()
{
string imsi = getArg("imsi");
string randx = getArg("rand");
string sres = getArg("sres");
string kc;
bool st = authenticate(imsi, randx, sres, &kc);
sresCheck(st);
}
// generate a 128' random number
void generateRandResponse()
{
string imsi = getArg("imsi");
string randx = generateRand(imsi);
gResponse.push_back("rand=" + randx);
gResponse.push_back("imsi=" + imsi);
}
// generate our http response, putting each line of it into vector response
void generateResponse()
{
if (gArgs.find("req") == gArgs.end()) {
LOG(ERR) << "req not specified";
return;
}
// check for request types
string req = gArgs["req"];
if (req == "sql") {
generateSqlResponse();
return;
}
if (req == "rand") {
generateRandResponse();
return;
}
if (req == "auth") {
generateAuthResponse();
return;
}
// if none of the above, then it's an error
LOG(ERR) << "unrecognized request";
}
// write the query to the log file
void logQuery()
{
// list query key->value pairs
map<string,string>::iterator it;
LOG(INFO) << "query";
for (it = gArgs.begin(); it != gArgs.end(); it++) {
LOG(INFO) << " " << it->first << " -> " << it->second;
}
}
// write the http response from the global array @response to the log file
void logResponse()
{
LOG(INFO) << "response";
vector<string>::iterator it;
for (it = gResponse.begin(); it != gResponse.end(); it++) {
LOG(INFO) << " " << *it;
}
}
// print the http response to stdout
void respond()
{
vector<string>::iterator it;
for (it = gResponse.begin(); it != gResponse.end(); it++) {
cout << *it << endl;
}
}
int main()
{
cout << "Content-Type: text\n\n";
srand ( time(NULL) + (int)getpid() );
// decode the http query
decodeQuery(gArgs);
// write the http query into the log file
logQuery();
// put the http response into the global array @response
generateResponse();
// write the http response to the log file
logResponse();
// print out the http response to stdout
respond();
}

View File

@ -0,0 +1,10 @@
TRUNK=../../../
COM=$(TRUNK)/CommonLibs/trunk/
SQL=$(TRUNK)/sqlite3/trunk/
LOCALLIBS=$(COM)/Logger.cpp $(COM)/Timeval.cpp $(COM)/Threads.cpp $(COM)/Sockets.cpp $(COM)/Configuration.cpp $(SQL)/sqlite3util.cpp
LIBS=$(LOCALLIBS) -losipparser2 -losip2 -lc -lpthread -lsqlite3
INCLUDES=-I$(COM) -I$(SQL)
CPPFLAGS=-g -Wall -Wno-deprecated
test: test.cpp ../SubscriberRegistry.cpp
g++ -o test $(CPPFLAGS) $(INCLUDES) test.cpp ../SubscriberRegistry.cpp $(LIBS)

View File

@ -0,0 +1,127 @@
Thu Apr 21 20:36:23 PDT 2011
../SubscriberRegistry.cpp:-0-:addUser: addUser(imsi,clid)
../SubscriberRegistry.cpp:-0-:sqlUpdate: insert into sip_buddies (name, username, type, context, host, callerid, canreinvite, allow, dtmfmode) values ("imsi","imsi","friend","phones","dynamic","clid","no","gsm","info");
../SubscriberRegistry.cpp:-0-:sqlLocal: insert into sip_buddies (name, username, type, context, host, callerid, canreinvite, allow, dtmfmode) values ("imsi","imsi","friend","phones","dynamic","clid","no","gsm","info");
../SubscriberRegistry.cpp:-0-:sqlHttp: insert into sip_buddies (name, username, type, context, host, callerid, canreinvite, allow, dtmfmode) values ("imsi","imsi","friend","phones","dynamic","clid","no","gsm","info");
../SubscriberRegistry.cpp:-0-:sqlUpdate: insert into dialdata_table (exten, dial) values ("clid","imsi")
../SubscriberRegistry.cpp:-0-:sqlLocal: insert into dialdata_table (exten, dial) values ("clid","imsi")
../SubscriberRegistry.cpp:-0-:sqlHttp: insert into dialdata_table (exten, dial) values ("clid","imsi")
../SubscriberRegistry.cpp:-0-:getCLIDLocal: getCLIDLocal(imsi)
../SubscriberRegistry.cpp:-0-:sqlLocal: select callerid from sip_buddies where name = "imsi"
../SubscriberRegistry.cpp:-0-:sqlQuery: result = clid
../SubscriberRegistry.cpp:-0-:getIMSI: getIMSI(clid)
../SubscriberRegistry.cpp:-0-:sqlLocal: select dial from dialdata_table where exten = "clid"
../SubscriberRegistry.cpp:-0-:sqlQuery: result = imsi
../SubscriberRegistry.cpp:-0-:getCLIDLocal: getCLIDLocal(imsi_unknown)
../SubscriberRegistry.cpp:-0-:sqlLocal: select callerid from sip_buddies where name = "imsi_unknown"
../SubscriberRegistry.cpp:-0-:sqlHttp: select callerid from sip_buddies where name = "imsi_unknown"
../SubscriberRegistry.cpp:-0-:sqlQuery: not found
../SubscriberRegistry.cpp:-0-:getRandForAuthentication: getRandForAuthentication(imsi_r1)
../SubscriberRegistry.cpp:-0-:log: imsi=imsi_r1&req=rand
../SubscriberRegistry.cpp:-0-:authenticate: authenticate(imsi_a1,rand_a1,sres_a1)
../SubscriberRegistry.cpp:-0-:log: imsi=imsi_a1&rand=rand_a1&req=auth&sres=sres_a1
test.cpp:-0-:foo: hexh1000 hexh1000
test.cpp:-0-:foo: hexh1001 hexh1001
test.cpp:-0-:foo: hexh1002 hexh1002
test.cpp:-0-:foo: hexh1003 hexh1003
test.cpp:-0-:foo: hexhexhexhexhexhexhexhexhexh1004 hexhexhexhexhexhexhexhexhexh1004
test.cpp:-0-:foo: hexhexhexhexhexhexhexhexhexh1005 hexhexhexhexhexhexhexhexhexh1005
test.cpp:-0-:foo: hexhexhexhexhexhexhexhexhexh1006 hexhexhexhexhexhexhexhexhexh1006
../SubscriberRegistry.cpp:-0-:sqlUpdate: update sip_buddies set prepaid = 0 where name = "imsi"
../SubscriberRegistry.cpp:-0-:sqlLocal: update sip_buddies set prepaid = 0 where name = "imsi"
../SubscriberRegistry.cpp:-0-:sqlHttp: update sip_buddies set prepaid = 0 where name = "imsi"
../SubscriberRegistry.cpp:-0-:sqlLocal: select prepaid from sip_buddies where name = "imsi"
../SubscriberRegistry.cpp:-0-:sqlQuery: result = 0
test.cpp:-0-:main: should be false 0
../SubscriberRegistry.cpp:-0-:sqlUpdate: update sip_buddies set prepaid = 1 where name = "imsi"
../SubscriberRegistry.cpp:-0-:sqlLocal: update sip_buddies set prepaid = 1 where name = "imsi"
../SubscriberRegistry.cpp:-0-:sqlHttp: update sip_buddies set prepaid = 1 where name = "imsi"
../SubscriberRegistry.cpp:-0-:sqlLocal: select prepaid from sip_buddies where name = "imsi"
../SubscriberRegistry.cpp:-0-:sqlQuery: result = 1
test.cpp:-0-:main: should be true 1
../SubscriberRegistry.cpp:-0-:sqlUpdate: update sip_buddies set secondsRemaining = 100 where name = "imsi"
../SubscriberRegistry.cpp:-0-:sqlLocal: update sip_buddies set secondsRemaining = 100 where name = "imsi"
../SubscriberRegistry.cpp:-0-:sqlHttp: update sip_buddies set secondsRemaining = 100 where name = "imsi"
../SubscriberRegistry.cpp:-0-:sqlLocal: select secondsRemaining from sip_buddies where name = "imsi"
../SubscriberRegistry.cpp:-0-:sqlQuery: result = 100
test.cpp:-0-:main: should be 100 100
../SubscriberRegistry.cpp:-0-:sqlUpdate: update sip_buddies set secondsRemaining = secondsRemaining + -50 where name = "imsi"
../SubscriberRegistry.cpp:-0-:sqlLocal: update sip_buddies set secondsRemaining = secondsRemaining + -50 where name = "imsi"
../SubscriberRegistry.cpp:-0-:sqlHttp: update sip_buddies set secondsRemaining = secondsRemaining + -50 where name = "imsi"
../SubscriberRegistry.cpp:-0-:sqlLocal: select secondsRemaining from sip_buddies where name = "imsi"
../SubscriberRegistry.cpp:-0-:sqlQuery: result = 50
test.cpp:-0-:main: should be 50 50
../SubscriberRegistry.cpp:-0-:sqlUpdate: update sip_buddies set secondsRemaining = secondsRemaining + -100 where name = "imsi"
../SubscriberRegistry.cpp:-0-:sqlLocal: update sip_buddies set secondsRemaining = secondsRemaining + -100 where name = "imsi"
../SubscriberRegistry.cpp:-0-:sqlHttp: update sip_buddies set secondsRemaining = secondsRemaining + -100 where name = "imsi"
../SubscriberRegistry.cpp:-0-:sqlLocal: select secondsRemaining from sip_buddies where name = "imsi"
../SubscriberRegistry.cpp:-0-:sqlQuery: result = -50
test.cpp:-0-:main: should be 0 0
../SubscriberRegistry.cpp:-0-:addUser: addUser(imsi,clid)
../SubscriberRegistry.cpp:-0-:sqlUpdate: insert into sip_buddies (name, username, type, context, host, callerid, canreinvite, allow, dtmfmode) values ("imsi","imsi","friend","phones","dynamic","clid","no","gsm","info");
../SubscriberRegistry.cpp:-0-:sqlLocal: insert into sip_buddies (name, username, type, context, host, callerid, canreinvite, allow, dtmfmode) values ("imsi","imsi","friend","phones","dynamic","clid","no","gsm","info");
../SubscriberRegistry.cpp:-0-:sqlHttp: insert into sip_buddies (name, username, type, context, host, callerid, canreinvite, allow, dtmfmode) values ("imsi","imsi","friend","phones","dynamic","clid","no","gsm","info");
../SubscriberRegistry.cpp:-0-:http: curl -s --data-binary @/tmp/subscriberregistry.1.-PID- testing > /tmp/subscriberregistry.2.-PID-
../SubscriberRegistry.cpp:-0-:sqlUpdate: insert into dialdata_table (exten, dial) values ("clid","imsi")
../SubscriberRegistry.cpp:-0-:sqlLocal: insert into dialdata_table (exten, dial) values ("clid","imsi")
../SubscriberRegistry.cpp:-0-:sqlHttp: insert into dialdata_table (exten, dial) values ("clid","imsi")
../SubscriberRegistry.cpp:-0-:http: curl -s --data-binary @/tmp/subscriberregistry.1.-PID- testing > /tmp/subscriberregistry.2.-PID-
../SubscriberRegistry.cpp:-0-:getCLIDLocal: getCLIDLocal(imsi)
../SubscriberRegistry.cpp:-0-:sqlLocal: select callerid from sip_buddies where name = "imsi"
../SubscriberRegistry.cpp:-0-:sqlQuery: result = clid
../SubscriberRegistry.cpp:-0-:getIMSI: getIMSI(clid)
../SubscriberRegistry.cpp:-0-:sqlLocal: select dial from dialdata_table where exten = "clid"
../SubscriberRegistry.cpp:-0-:sqlQuery: result = imsi
../SubscriberRegistry.cpp:-0-:getCLIDLocal: getCLIDLocal(imsi_unknown)
../SubscriberRegistry.cpp:-0-:sqlLocal: select callerid from sip_buddies where name = "imsi_unknown"
../SubscriberRegistry.cpp:-0-:sqlHttp: select callerid from sip_buddies where name = "imsi_unknown"
../SubscriberRegistry.cpp:-0-:http: curl -s --data-binary @/tmp/subscriberregistry.1.-PID- testing > /tmp/subscriberregistry.2.-PID-
../SubscriberRegistry.cpp:-0-:sqlQuery: not found
../SubscriberRegistry.cpp:-0-:getRandForAuthentication: getRandForAuthentication(imsi_r1)
../SubscriberRegistry.cpp:-0-:log: imsi=imsi_r1&req=rand
../SubscriberRegistry.cpp:-0-:http: curl -s --data-binary @/tmp/subscriberregistry.1.-PID- testing > /tmp/subscriberregistry.2.-PID-
../SubscriberRegistry.cpp:-0-:authenticate: authenticate(imsi_a1,rand_a1,sres_a1)
../SubscriberRegistry.cpp:-0-:log: imsi=imsi_a1&rand=rand_a1&req=auth&sres=sres_a1
../SubscriberRegistry.cpp:-0-:http: curl -s --data-binary @/tmp/subscriberregistry.1.-PID- testing > /tmp/subscriberregistry.2.-PID-
test.cpp:-0-:foo: hexh1000 hexh1000
test.cpp:-0-:foo: hexh1001 hexh1001
test.cpp:-0-:foo: hexh1002 hexh1002
test.cpp:-0-:foo: hexh1003 hexh1003
test.cpp:-0-:foo: hexhexhexhexhexhexhexhexhexh1004 hexhexhexhexhexhexhexhexhexh1004
test.cpp:-0-:foo: hexhexhexhexhexhexhexhexhexh1005 hexhexhexhexhexhexhexhexhexh1005
test.cpp:-0-:foo: hexhexhexhexhexhexhexhexhexh1006 hexhexhexhexhexhexhexhexhexh1006
../SubscriberRegistry.cpp:-0-:sqlUpdate: update sip_buddies set prepaid = 0 where name = "imsi"
../SubscriberRegistry.cpp:-0-:sqlLocal: update sip_buddies set prepaid = 0 where name = "imsi"
../SubscriberRegistry.cpp:-0-:sqlHttp: update sip_buddies set prepaid = 0 where name = "imsi"
../SubscriberRegistry.cpp:-0-:http: curl -s --data-binary @/tmp/subscriberregistry.1.-PID- testing > /tmp/subscriberregistry.2.-PID-
../SubscriberRegistry.cpp:-0-:sqlLocal: select prepaid from sip_buddies where name = "imsi"
../SubscriberRegistry.cpp:-0-:sqlQuery: result = 0
test.cpp:-0-:main: should be false 0
../SubscriberRegistry.cpp:-0-:sqlUpdate: update sip_buddies set prepaid = 1 where name = "imsi"
../SubscriberRegistry.cpp:-0-:sqlLocal: update sip_buddies set prepaid = 1 where name = "imsi"
../SubscriberRegistry.cpp:-0-:sqlHttp: update sip_buddies set prepaid = 1 where name = "imsi"
../SubscriberRegistry.cpp:-0-:http: curl -s --data-binary @/tmp/subscriberregistry.1.-PID- testing > /tmp/subscriberregistry.2.-PID-
../SubscriberRegistry.cpp:-0-:sqlLocal: select prepaid from sip_buddies where name = "imsi"
../SubscriberRegistry.cpp:-0-:sqlQuery: result = 1
test.cpp:-0-:main: should be true 1
../SubscriberRegistry.cpp:-0-:sqlUpdate: update sip_buddies set secondsRemaining = 100 where name = "imsi"
../SubscriberRegistry.cpp:-0-:sqlLocal: update sip_buddies set secondsRemaining = 100 where name = "imsi"
../SubscriberRegistry.cpp:-0-:sqlHttp: update sip_buddies set secondsRemaining = 100 where name = "imsi"
../SubscriberRegistry.cpp:-0-:http: curl -s --data-binary @/tmp/subscriberregistry.1.-PID- testing > /tmp/subscriberregistry.2.-PID-
../SubscriberRegistry.cpp:-0-:sqlLocal: select secondsRemaining from sip_buddies where name = "imsi"
../SubscriberRegistry.cpp:-0-:sqlQuery: result = 100
test.cpp:-0-:main: should be 100 100
../SubscriberRegistry.cpp:-0-:sqlUpdate: update sip_buddies set secondsRemaining = secondsRemaining + -50 where name = "imsi"
../SubscriberRegistry.cpp:-0-:sqlLocal: update sip_buddies set secondsRemaining = secondsRemaining + -50 where name = "imsi"
../SubscriberRegistry.cpp:-0-:sqlHttp: update sip_buddies set secondsRemaining = secondsRemaining + -50 where name = "imsi"
../SubscriberRegistry.cpp:-0-:http: curl -s --data-binary @/tmp/subscriberregistry.1.-PID- testing > /tmp/subscriberregistry.2.-PID-
../SubscriberRegistry.cpp:-0-:sqlLocal: select secondsRemaining from sip_buddies where name = "imsi"
../SubscriberRegistry.cpp:-0-:sqlQuery: result = 50
test.cpp:-0-:main: should be 50 50
../SubscriberRegistry.cpp:-0-:sqlUpdate: update sip_buddies set secondsRemaining = secondsRemaining + -100 where name = "imsi"
../SubscriberRegistry.cpp:-0-:sqlLocal: update sip_buddies set secondsRemaining = secondsRemaining + -100 where name = "imsi"
../SubscriberRegistry.cpp:-0-:sqlHttp: update sip_buddies set secondsRemaining = secondsRemaining + -100 where name = "imsi"
../SubscriberRegistry.cpp:-0-:http: curl -s --data-binary @/tmp/subscriberregistry.1.-PID- testing > /tmp/subscriberregistry.2.-PID-
../SubscriberRegistry.cpp:-0-:sqlLocal: select secondsRemaining from sip_buddies where name = "imsi"
../SubscriberRegistry.cpp:-0-:sqlQuery: result = -50
test.cpp:-0-:main: should be 0 0

23
test.SubscriberRegistry/runtest Executable file
View File

@ -0,0 +1,23 @@
#!/bin/bash
make test
logger -plocal7.Debug dwb syslog mark
date > output.got
# first run without a remote http server
rm -f test.db sr.db
sqlite3 test.db < test.db.init1
sqlite3 sr.db < sr.db.init
./test
# then run with a remote http server
rm -f test.db sr.db
sqlite3 test.db < test.db.init2
sqlite3 sr.db < sr.db.init
./test
../syslogextractor >> output.got
mv output.got ootput.got
../hexmapper ootput.got > output.got
diff output.exp output.got
exit 0

View File

@ -0,0 +1,106 @@
create table dialdata_table (
id INTEGER,
exten VARCHAR(40) NOT NULL DEFAULT '',
dial VARCHAR(128) NOT NULL DEFAULT '',
PRIMARY KEY (id)
);
-- INSERT INTO dialdata_table (exten, dial) VALUES ('1000', '1000');
-- INSERT INTO dialdata_table (exten, dial) VALUES ('1001', '1001');
CREATE TABLE 'sip_buddies'
(
id integer,
name VARCHAR(80) unique not null,
context VARCHAR(80),
callingpres VARCHAR(30) DEFAULT 'allowed_not_screened',
deny VARCHAR(95),
permit VARCHAR(95),
secret VARCHAR(80),
md5secret VARCHAR(80),
remotesecret VARCHAR(250),
transport VARCHAR(10),
host VARCHAR(31) DEFAULT '' not null,
nat VARCHAR(5) DEFAULT 'no' not null,
type VARCHAR(10) DEFAULT 'friend' not null,
accountcode VARCHAR(20),
amaflags VARCHAR(13),
callgroup VARCHAR(10),
callerid VARCHAR(80),
defaultip VARCHAR(40) DEFAULT '0.0.0.0',
dtmfmode VARCHAR(7) DEFAULT 'rfc2833',
fromuser VARCHAR(80),
fromdomain VARCHAR(80),
insecure VARCHAR(4),
language CHAR(2),
mailbox VARCHAR(50),
pickupgroup VARCHAR(10),
qualify CHAR(3),
regexten VARCHAR(80),
rtptimeout CHAR(3),
rtpholdtimeout CHAR(3),
setvar VARCHAR(100),
disallow VARCHAR(100) DEFAULT 'all',
allow VARCHAR(100) DEFAULT 'ulaw' not null,
fullcontact VARCHAR(80),
ipaddr VARCHAR(40),
port int(5) DEFAULT 0,
username VARCHAR(80),
defaultuser VARCHAR(80),
subscribecontext VARCHAR(80),
directmedia VARCHAR(3),
trustrpid VARCHAR(3),
sendrpid VARCHAR(3),
progressinband VARCHAR(5),
promiscredir VARCHAR(3),
useclientcode VARCHAR(3),
callcounter VARCHAR(3),
busylevel int(11),
allowoverlap VARCHAR(3) DEFAULT 'yes',
allowsubscribe VARCHAR(3) DEFAULT 'yes',
allowtransfer VARCHAR(3) DEFAULT 'yes',
ignoresdpversion VARCHAR(3) DEFAULT 'no',
template VARCHAR(100),
videosupport VARCHAR(6) DEFAULT 'no',
maxcallbitrate int(11),
rfc2833compensate VARCHAR(3) DEFAULT 'yes',
'session-timers' VARCHAR(10) DEFAULT 'accept',
'session-expires' int(6) DEFAULT 1800,
'session-minse' int(6) DEFAULT 90,
'session-refresher' VARCHAR(3) DEFAULT 'uas',
t38pt_usertpsource VARCHAR(3),
outboundproxy VARCHAR(250),
callbackextension VARCHAR(250),
registertrying VARCHAR(3) DEFAULT 'yes',
timert1 int(6) DEFAULT 500,
timerb int(9),
qualifyfreq int(6) DEFAULT 120,
contactpermit VARCHAR(250),
contactdeny VARCHAR(250),
lastms int(11) DEFAULT 0 not null,
regserver VARCHAR(100),
regseconds int(11) DEFAULT 0 not null,
useragent VARCHAR(100),
cancallforward CHAR(3) DEFAULT 'yes' not null,
canreinvite CHAR(3) DEFAULT 'yes' not null,
mask VARCHAR(95),
musiconhold VARCHAR(100),
restrictcid CHAR(3),
calllimit int(5),
ki VARCHAR(32) DEFAULT '' not null,
rand VARCHAR(32) DEFAULT '' not null,
sres VARCHAR(32) DEFAULT '' not null,
prepaid int(1),
secondsRemaining int(11),
primary key(id)
)
;
-- insert into sip_buddies (name,username,type,context,host) values ('1000','1000','friend','phones','dynamic');
-- insert into sip_buddies (name,username,type,context,host) values ('1001','1001','friend','phones','dynamic');
-- insert into sip_buddies (name,ipaddr) values ('imsi2','imsi2ipaddr');
-- insert into sip_buddies (name) values('imsi_r1'); -- rand should generate
-- insert into sip_buddies (name,rand) values('imsi_r2','12345678901234567890123456789012'); -- rand should return this
-- insert into sip_buddies (name,ki) values ('imsi_a1','7f4d7fbff290e20e60466bc7b5b08e4b'); -- auth should calc
-- insert into sip_buddies (name) values ('imsi_a2'); -- auth should save passed rand and sres
-- insert into sip_buddies (name,rand,sres) values ('imsi_a3','123456789012345678901234567890a3','1234567890123456789012a3'); -- auth should verify rand and sres

View File

@ -0,0 +1,80 @@
#include <string.h>
#include <iostream>
#include <sstream>
#include <fstream>
#include "../SubscriberRegistry.h"
#include "Configuration.h"
using namespace std;
ConfigurationTable gConfig("test.db");
SubscriberRegistry sr;
void foo(uint32_t n, string s)
{
LOG(INFO) << sr.uintToString(n) << " " << s;
}
void foo(string s)
{
uint64_t h;
uint64_t l;
sr.stringToUint(s, &h, &l);
LOG(INFO) << sr.uintToString(h, l) << " " << s;
}
int main(int argc, char **argv)
{
gLogInit("SubscriberRegistryTest",gConfig.getStr("Log.Level").c_str(),LOG_LOCAL7);
// The idea is just to make sure things are connected right. The important code is shared, and tested elsewhere.
// add a user
sr.addUser("imsi", "clid");
// testing mappings of known user
sr.getCLIDLocal("imsi");
sr.getIMSI("clid");
// test mapping of unknow user (so it won't be found locally)
sr.getCLIDLocal("imsi_unknown");
sr.getRandForAuthentication(false, "imsi_r1");
sr.authenticate(false, "imsi_a1","rand_a1","sres_a1");
// but test the conversions
foo(0xffffffff, "ffffffff");
foo(0x00000000, "00000000");
foo(0x12345678, "12345678");
foo(0x9abcdef0, "9abcdef0");
foo("ffffffffffffffff0000000000000000");
foo("0000000000000000ffffffffffffffff");
foo("0123456789abcdef0123456789abcdef");
// billing testing - not tested elsewhere
sr.setPrepaid("imsi", false);
bool b;
sr.isPrepaid("imsi", b);
LOG(INFO) << "should be false " << b;
sr.setPrepaid("imsi", true);
sr.isPrepaid("imsi", b);
LOG(INFO) << "should be true " << b;
sr.setSeconds("imsi", 100);
int t;
sr.secondsRemaining("imsi", t);
LOG(INFO) << "should be 100 " << t;
sr.addSeconds("imsi", -50, t);
LOG(INFO) << "should be 50 " << t;
sr.addSeconds("imsi", -100, t);
LOG(INFO) << "should be 0 " << t;
}

View File

@ -0,0 +1,8 @@
BEGIN TRANSACTION;
CREATE TABLE CONFIG ( KEYSTRING TEXT UNIQUE NOT NULL, VALUESTRING TEXT, STATIC INTEGER DEFAULT 0, OPTIONAL INTEGER DEFAULT 0, COMMENTS TEXT DEFAULT '');
INSERT INTO "CONFIG" VALUES('Log.Level','DEBUG',0,0,'');
INSERT INTO "CONFIG" VALUES('SubscriberRegistry.db','sr.db',0,0,'');
INSERT INTO "CONFIG" VALUES('SubscriberRegistry.HTTP.Server','',0,0,'');
INSERT INTO "CONFIG" VALUES('SIP.Proxy.Registration','testing',0,0,'');
INSERT INTO "CONFIG" VALUES('SubscriberRegistry.UpstreamServer','',0,0,'');
COMMIT;

View File

@ -0,0 +1,8 @@
BEGIN TRANSACTION;
CREATE TABLE CONFIG ( KEYSTRING TEXT UNIQUE NOT NULL, VALUESTRING TEXT, STATIC INTEGER DEFAULT 0, OPTIONAL INTEGER DEFAULT 0, COMMENTS TEXT DEFAULT '');
INSERT INTO "CONFIG" VALUES('Log.Level','DEBUG',0,0,'');
INSERT INTO "CONFIG" VALUES('SubscriberRegistry.db','sr.db',0,0,'');
INSERT INTO "CONFIG" VALUES('SubscriberRegistry.HTTP.Server','testing',0,0,'');
INSERT INTO "CONFIG" VALUES('SIP.Proxy.Registration','testing',0,0,'');
INSERT INTO "CONFIG" VALUES('SubscriberRegistry.UpstreamServer','',0,0,'');
COMMIT;

View File

@ -0,0 +1,10 @@
REGISTER sip:localhost SIP/2.0
Via: SIP/2.0/UDP [5555::aaa:bbb:ccc:ddd]; comp=sigcomp;branch=z9hG4bKnashds7
Max-Forwards: 70
P-Access-Network-Info: 3GPP-UTRAN-TDD; utran-cell-id-3gpp=234151D0FCE11
From: <sip:EXIT>;tag=4fa3
To: <sip:EXIT>
Contact: <sip:[5555::aaa:bbb:ccc:ddd];comp=sigcomp>;expires=600000
CSeq: 1 REGISTER
Supported: path
Content-Length: 0

View File

@ -0,0 +1,572 @@
Fri Mar 18 16:47:33 PDT 2011
IMSI12345678901231|||known|
IMSI12345678901232||||
IMSI12345678901234|||hexhexhexhexhexhexhexhexhexh1000|
IMSI12345678901235||||
sipauthserve.cpp:-0-:prettyPrint: request:
REGISTER sip:localhost SIP/2.0^M
Via: SIP/2.0/UDP [5555::aaa:bbb:ccc:ddd];comp=sigcomp;branch=z9hG4bKnashds7^M
From: <sip:IMSI12345678901231>;tag=4fa3^M
To: <sip:user1_public1@localhost>^M
CSeq: 1 REGISTER^M
Contact: <sip:[5555::aaa:bbb:ccc:ddd];comp=sigcomp>;expires=600000^M
Max-forwards: 70^M
P-access-network-info: 3GPP-UTRAN-TDD; utran-cell-id-3gpp=234151D0FCE11^M
Supported: path^M
Content-Length: 0^M
^M
sipauthserve.cpp:-0-:processBuffer: imsi known, 1st register
servershare.cpp:-0-:generateRand: ki is known
sipauthserve.cpp:-0-:prettyPrint: response:
SIP/2.0 401 Unauthorized^M
Via: SIP/2.0/UDP localhost:5063;branch=1;received=string_address@foo.bar^M
Via: SIP/2.0/UDP [5555::aaa:bbb:ccc:ddd];comp=sigcomp;branch=z9hG4bKnashds7^M
From: <sip:IMSI12345678901231>;tag=4fa3^M
To: <sip:user1_public1@localhost>^M
CSeq: 1 REGISTER^M
Contact: <sip:[5555::aaa:bbb:ccc:ddd];comp=sigcomp>;expires=600000^M
WWW-Authenticate: Digest nonce=hexhexhexhexhexhexhexhexhexh1001^M
Max-forwards: 70^M
P-access-network-info: 3GPP-UTRAN-TDD; utran-cell-id-3gpp=234151D0FCE11^M
Supported: path^M
Content-Length: 0^M
^M
sipauthserve.cpp:-0-:processBuffer:
----------------
sipauthserve.cpp:-0-:prettyPrint: request:
REGISTER sip:localhost SIP/2.0^M
Via: SIP/2.0/UDP [5555::aaa:bbb:ccc:ddd];comp=sigcomp;branch=z9hG4bKnashds7^M
From: <sip:EXIT>;tag=4fa3^M
To: <sip:EXIT>^M
CSeq: 1 REGISTER^M
Contact: <sip:[5555::aaa:bbb:ccc:ddd];comp=sigcomp>;expires=600000^M
Max-forwards: 70^M
P-access-network-info: 3GPP-UTRAN-TDD; utran-cell-id-3gpp=234151D0FCE11^M
Supported: path^M
Content-Length: 0^M
^M
IMSI12345678901231|||known|
IMSI12345678901232||||
IMSI12345678901234|||hexhexhexhexhexhexhexhexhexh1000|
IMSI12345678901235||||
sipauthserve.cpp:-0-:prettyPrint: request:
REGISTER sip:localhost SIP/2.0^M
Via: SIP/2.0/UDP [5555::aaa:bbb:ccc:ddd];comp=sigcomp;branch=z9hG4bKnashds7^M
From: <sip:IMSI12345678901232>;tag=4fa3^M
To: <sip:user1_public1@localhost>^M
CSeq: 1 REGISTER^M
Contact: <sip:[5555::aaa:bbb:ccc:ddd];comp=sigcomp>;expires=600000^M
Max-forwards: 70^M
P-access-network-info: 3GPP-UTRAN-TDD; utran-cell-id-3gpp=234151D0FCE11^M
Supported: path^M
Content-Length: 0^M
^M
sipauthserve.cpp:-0-:processBuffer: imsi known, 1st register
servershare.cpp:-0-:generateRand: ki is unknown, rand is not cached
sipauthserve.cpp:-0-:prettyPrint: response:
SIP/2.0 401 Unauthorized^M
Via: SIP/2.0/UDP localhost:5063;branch=1;received=string_address@foo.bar^M
Via: SIP/2.0/UDP [5555::aaa:bbb:ccc:ddd];comp=sigcomp;branch=z9hG4bKnashds7^M
From: <sip:IMSI12345678901232>;tag=4fa3^M
To: <sip:user1_public1@localhost>^M
CSeq: 1 REGISTER^M
Contact: <sip:[5555::aaa:bbb:ccc:ddd];comp=sigcomp>;expires=600000^M
WWW-Authenticate: Digest nonce=hexhexhexhexhexhexhexhexhexh1002^M
Max-forwards: 70^M
P-access-network-info: 3GPP-UTRAN-TDD; utran-cell-id-3gpp=234151D0FCE11^M
Supported: path^M
Content-Length: 0^M
^M
sipauthserve.cpp:-0-:processBuffer:
----------------
sipauthserve.cpp:-0-:prettyPrint: request:
REGISTER sip:localhost SIP/2.0^M
Via: SIP/2.0/UDP [5555::aaa:bbb:ccc:ddd];comp=sigcomp;branch=z9hG4bKnashds7^M
From: <sip:EXIT>;tag=4fa3^M
To: <sip:EXIT>^M
CSeq: 1 REGISTER^M
Contact: <sip:[5555::aaa:bbb:ccc:ddd];comp=sigcomp>;expires=600000^M
Max-forwards: 70^M
P-access-network-info: 3GPP-UTRAN-TDD; utran-cell-id-3gpp=234151D0FCE11^M
Supported: path^M
Content-Length: 0^M
^M
IMSI12345678901231|||known|
IMSI12345678901232|hexhexhexhexhexhexhexhexhexh1002|||
IMSI12345678901234|||hexhexhexhexhexhexhexhexhexh1000|
IMSI12345678901235||||
sipauthserve.cpp:-0-:prettyPrint: request:
REGISTER sip:localhost SIP/2.0^M
Via: SIP/2.0/UDP [5555::aaa:bbb:ccc:ddd];comp=sigcomp;branch=z9hG4bKnashds7^M
From: <sip:IMSI12345678901232>;tag=4fa3^M
To: <sip:user1_public1@localhost>^M
CSeq: 1 REGISTER^M
Contact: <sip:[5555::aaa:bbb:ccc:ddd];comp=sigcomp>;expires=600000^M
Max-forwards: 70^M
P-access-network-info: 3GPP-UTRAN-TDD; utran-cell-id-3gpp=234151D0FCE11^M
Supported: path^M
Content-Length: 0^M
^M
sipauthserve.cpp:-0-:processBuffer: imsi known, 1st register
servershare.cpp:-0-:generateRand: ki is unknown, rand is cached
sipauthserve.cpp:-0-:prettyPrint: response:
SIP/2.0 401 Unauthorized^M
Via: SIP/2.0/UDP localhost:5063;branch=1;received=string_address@foo.bar^M
Via: SIP/2.0/UDP [5555::aaa:bbb:ccc:ddd];comp=sigcomp;branch=z9hG4bKnashds7^M
From: <sip:IMSI12345678901232>;tag=4fa3^M
To: <sip:user1_public1@localhost>^M
CSeq: 1 REGISTER^M
Contact: <sip:[5555::aaa:bbb:ccc:ddd];comp=sigcomp>;expires=600000^M
WWW-Authenticate: Digest nonce=hexhexhexhexhexhexhexhexhexh1002^M
Max-forwards: 70^M
P-access-network-info: 3GPP-UTRAN-TDD; utran-cell-id-3gpp=234151D0FCE11^M
Supported: path^M
Content-Length: 0^M
^M
sipauthserve.cpp:-0-:processBuffer:
----------------
sipauthserve.cpp:-0-:prettyPrint: request:
REGISTER sip:localhost SIP/2.0^M
Via: SIP/2.0/UDP [5555::aaa:bbb:ccc:ddd];comp=sigcomp;branch=z9hG4bKnashds7^M
From: <sip:EXIT>;tag=4fa3^M
To: <sip:EXIT>^M
CSeq: 1 REGISTER^M
Contact: <sip:[5555::aaa:bbb:ccc:ddd];comp=sigcomp>;expires=600000^M
Max-forwards: 70^M
P-access-network-info: 3GPP-UTRAN-TDD; utran-cell-id-3gpp=234151D0FCE11^M
Supported: path^M
Content-Length: 0^M
^M
IMSI12345678901231|||known|
IMSI12345678901232|hexhexhexhexhexhexhexhexhexh1002|||
IMSI12345678901234|||hexhexhexhexhexhexhexhexhexh1000|
IMSI12345678901235||||
sipauthserve.cpp:-0-:prettyPrint: request:
REGISTER sip:localhost SIP/2.0^M
Via: SIP/2.0/UDP [5555::aaa:bbb:ccc:ddd];comp=sigcomp;branch=z9hG4bKnashds7^M
From: <sip:IMSI12345678901233>;tag=4fa3^M
To: <sip:user1_public1@localhost>^M
CSeq: 1 REGISTER^M
Contact: <sip:[5555::aaa:bbb:ccc:ddd];comp=sigcomp>;expires=600000^M
Max-forwards: 70^M
P-access-network-info: 3GPP-UTRAN-TDD; utran-cell-id-3gpp=234151D0FCE11^M
Supported: path^M
Content-Length: 0^M
^M
sipauthserve.cpp:-0-:processBuffer: imsi unknown
sipauthserve.cpp:-0-:prettyPrint: response:
SIP/2.0 404 IMSI Not Found^M
Via: SIP/2.0/UDP localhost:5063;branch=1;received=string_address@foo.bar^M
Via: SIP/2.0/UDP [5555::aaa:bbb:ccc:ddd];comp=sigcomp;branch=z9hG4bKnashds7^M
From: <sip:IMSI12345678901233>;tag=4fa3^M
To: <sip:user1_public1@localhost>^M
CSeq: 1 REGISTER^M
Contact: <sip:[5555::aaa:bbb:ccc:ddd];comp=sigcomp>;expires=600000^M
Max-forwards: 70^M
P-access-network-info: 3GPP-UTRAN-TDD; utran-cell-id-3gpp=234151D0FCE11^M
Supported: path^M
Content-Length: 0^M
^M
sipauthserve.cpp:-0-:processBuffer:
----------------
sipauthserve.cpp:-0-:prettyPrint: request:
REGISTER sip:localhost SIP/2.0^M
Via: SIP/2.0/UDP [5555::aaa:bbb:ccc:ddd];comp=sigcomp;branch=z9hG4bKnashds7^M
From: <sip:EXIT>;tag=4fa3^M
To: <sip:EXIT>^M
CSeq: 1 REGISTER^M
Contact: <sip:[5555::aaa:bbb:ccc:ddd];comp=sigcomp>;expires=600000^M
Max-forwards: 70^M
P-access-network-info: 3GPP-UTRAN-TDD; utran-cell-id-3gpp=234151D0FCE11^M
Supported: path^M
Content-Length: 0^M
^M
IMSI12345678901231|||known|
IMSI12345678901232|hexhexhexhexhexhexhexhexhexh1002|||
IMSI12345678901234|||hexhexhexhexhexhexhexhexhexh1000|
IMSI12345678901235||||
sipauthserve.cpp:-0-:prettyPrint: request:
REGISTER sip:localhost SIP/2.0^M
Via: SIP/2.0/UDP [5555::aaa:bbb:ccc:ddd];comp=sigcomp;branch=z9hG4bKnashds7^M
From: <sip:IMSI12345678901234>;tag=4fa3^M
To: <sip:user1_public1@localhost>^M
CSeq: 1 REGISTER^M
Contact: <sip:[5555::aaa:bbb:ccc:ddd];comp=sigcomp>;expires=600000^M
Authorization: Digest, nonce="hexhexhexhexhexhexhexhexhexh1003", uri="sip:IMSI12345678904321", response="hexhexhexhexhexhexhe1004"^M
Max-forwards: 70^M
P-access-network-info: 3GPP-UTRAN-TDD; utran-cell-id-3gpp=234151D0FCE11^M
Supported: path^M
Content-Length: 0^M
^M
sipauthserve.cpp:-0-:processBuffer: imsi known, 2nd register
servershare.cpp:-0-:authenticate: ki known
servershare.cpp:-0-:authenticate: result = hexh1005
servershare.cpp:-0-:authenticate: returning = 1
sipauthserve.cpp:-0-:prettyPrint: response:
SIP/2.0 200 OK^M
Via: SIP/2.0/UDP localhost:5063;branch=1;received=string_address@foo.bar^M
Via: SIP/2.0/UDP [5555::aaa:bbb:ccc:ddd];comp=sigcomp;branch=z9hG4bKnashds7^M
From: <sip:IMSI12345678901234>;tag=4fa3^M
To: <sip:user1_public1@localhost>^M
CSeq: 1 REGISTER^M
Contact: <sip:[5555::aaa:bbb:ccc:ddd];comp=sigcomp>;expires=600000^M
Authorization: Digest, nonce="hexhexhexhexhexhexhexhexhexh1003", uri="sip:IMSI12345678904321", response="hexhexhexhexhexhexhe1004"^M
Max-forwards: 70^M
P-access-network-info: 3GPP-UTRAN-TDD; utran-cell-id-3gpp=234151D0FCE11^M
Supported: path^M
Content-Length: 0^M
^M
sipauthserve.cpp:-0-:processBuffer:
----------------
sipauthserve.cpp:-0-:prettyPrint: request:
REGISTER sip:localhost SIP/2.0^M
Via: SIP/2.0/UDP [5555::aaa:bbb:ccc:ddd];comp=sigcomp;branch=z9hG4bKnashds7^M
From: <sip:EXIT>;tag=4fa3^M
To: <sip:EXIT>^M
CSeq: 1 REGISTER^M
Contact: <sip:[5555::aaa:bbb:ccc:ddd];comp=sigcomp>;expires=600000^M
Max-forwards: 70^M
P-access-network-info: 3GPP-UTRAN-TDD; utran-cell-id-3gpp=234151D0FCE11^M
Supported: path^M
Content-Length: 0^M
^M
IMSI12345678901231|||known|
IMSI12345678901232|hexhexhexhexhexhexhexhexhexh1002|||
IMSI12345678901234|||hexhexhexhexhexhexhexhexhexh1000|
IMSI12345678901235||||
sipauthserve.cpp:-0-:prettyPrint: request:
REGISTER sip:localhost SIP/2.0^M
Via: SIP/2.0/UDP [5555::aaa:bbb:ccc:ddd];comp=sigcomp;branch=z9hG4bKnashds7^M
From: <sip:IMSI12345678901234>;tag=4fa3^M
To: <sip:user1_public1@localhost>^M
CSeq: 1 REGISTER^M
Contact: <sip:[5555::aaa:bbb:ccc:ddd];comp=sigcomp>;expires=600000^M
Authorization: Digest, nonce="hexhexhexhexhexhexhexhexhexh1006", uri="sip:IMSI12345678904321", response="hexhexhexhexhexhexhe1004"^M
Max-forwards: 70^M
P-access-network-info: 3GPP-UTRAN-TDD; utran-cell-id-3gpp=234151D0FCE11^M
Supported: path^M
Content-Length: 0^M
^M
sipauthserve.cpp:-0-:processBuffer: imsi known, 2nd register
servershare.cpp:-0-:authenticate: ki known
servershare.cpp:-0-:authenticate: result = hexh1007
servershare.cpp:-0-:authenticate: returning = 0
sipauthserve.cpp:-0-:prettyPrint: response:
SIP/2.0 401 Unauthorized^M
Via: SIP/2.0/UDP localhost:5063;branch=1;received=string_address@foo.bar^M
Via: SIP/2.0/UDP [5555::aaa:bbb:ccc:ddd];comp=sigcomp;branch=z9hG4bKnashds7^M
From: <sip:IMSI12345678901234>;tag=4fa3^M
To: <sip:user1_public1@localhost>^M
CSeq: 1 REGISTER^M
Contact: <sip:[5555::aaa:bbb:ccc:ddd];comp=sigcomp>;expires=600000^M
Authorization: Digest, nonce="hexhexhexhexhexhexhexhexhexh1006", uri="sip:IMSI12345678904321", response="hexhexhexhexhexhexhe1004"^M
Max-forwards: 70^M
P-access-network-info: 3GPP-UTRAN-TDD; utran-cell-id-3gpp=234151D0FCE11^M
Supported: path^M
Content-Length: 0^M
^M
sipauthserve.cpp:-0-:processBuffer:
----------------
sipauthserve.cpp:-0-:prettyPrint: request:
REGISTER sip:localhost SIP/2.0^M
Via: SIP/2.0/UDP [5555::aaa:bbb:ccc:ddd];comp=sigcomp;branch=z9hG4bKnashds7^M
From: <sip:EXIT>;tag=4fa3^M
To: <sip:EXIT>^M
CSeq: 1 REGISTER^M
Contact: <sip:[5555::aaa:bbb:ccc:ddd];comp=sigcomp>;expires=600000^M
Max-forwards: 70^M
P-access-network-info: 3GPP-UTRAN-TDD; utran-cell-id-3gpp=234151D0FCE11^M
Supported: path^M
Content-Length: 0^M
^M
IMSI12345678901231|||known|
IMSI12345678901232|hexhexhexhexhexhexhexhexhexh1002|||
IMSI12345678901234|||hexhexhexhexhexhexhexhexhexh1000|
IMSI12345678901235||||
sipauthserve.cpp:-0-:prettyPrint: request:
REGISTER sip:localhost SIP/2.0^M
Via: SIP/2.0/UDP [5555::aaa:bbb:ccc:ddd];comp=sigcomp;branch=z9hG4bKnashds7^M
From: <sip:IMSI12345678901234>;tag=4fa3^M
To: <sip:user1_public1@localhost>^M
CSeq: 1 REGISTER^M
Contact: <sip:[5555::aaa:bbb:ccc:ddd];comp=sigcomp>;expires=600000^M
Authorization: Digest, nonce="hexhexhexhexhexhexhexhexhexh1003", uri="sip:IMSI12345678904321", response="hexhexhexhexhexhexhe1008"^M
Max-forwards: 70^M
P-access-network-info: 3GPP-UTRAN-TDD; utran-cell-id-3gpp=234151D0FCE11^M
Supported: path^M
Content-Length: 0^M
^M
sipauthserve.cpp:-0-:processBuffer: imsi known, 2nd register
servershare.cpp:-0-:authenticate: ki known
servershare.cpp:-0-:authenticate: result = hexh1005
servershare.cpp:-0-:authenticate: returning = 0
sipauthserve.cpp:-0-:prettyPrint: response:
SIP/2.0 401 Unauthorized^M
Via: SIP/2.0/UDP localhost:5063;branch=1;received=string_address@foo.bar^M
Via: SIP/2.0/UDP [5555::aaa:bbb:ccc:ddd];comp=sigcomp;branch=z9hG4bKnashds7^M
From: <sip:IMSI12345678901234>;tag=4fa3^M
To: <sip:user1_public1@localhost>^M
CSeq: 1 REGISTER^M
Contact: <sip:[5555::aaa:bbb:ccc:ddd];comp=sigcomp>;expires=600000^M
Authorization: Digest, nonce="hexhexhexhexhexhexhexhexhexh1003", uri="sip:IMSI12345678904321", response="hexhexhexhexhexhexhe1008"^M
Max-forwards: 70^M
P-access-network-info: 3GPP-UTRAN-TDD; utran-cell-id-3gpp=234151D0FCE11^M
Supported: path^M
Content-Length: 0^M
^M
sipauthserve.cpp:-0-:processBuffer:
----------------
sipauthserve.cpp:-0-:prettyPrint: request:
REGISTER sip:localhost SIP/2.0^M
Via: SIP/2.0/UDP [5555::aaa:bbb:ccc:ddd];comp=sigcomp;branch=z9hG4bKnashds7^M
From: <sip:EXIT>;tag=4fa3^M
To: <sip:EXIT>^M
CSeq: 1 REGISTER^M
Contact: <sip:[5555::aaa:bbb:ccc:ddd];comp=sigcomp>;expires=600000^M
Max-forwards: 70^M
P-access-network-info: 3GPP-UTRAN-TDD; utran-cell-id-3gpp=234151D0FCE11^M
Supported: path^M
Content-Length: 0^M
^M
IMSI12345678901231|||known|
IMSI12345678901232|hexhexhexhexhexhexhexhexhexh1002|||
IMSI12345678901234|||hexhexhexhexhexhexhexhexhexh1000|
IMSI12345678901235||||
sipauthserve.cpp:-0-:prettyPrint: request:
REGISTER sip:localhost SIP/2.0^M
Via: SIP/2.0/UDP [5555::aaa:bbb:ccc:ddd];comp=sigcomp;branch=z9hG4bKnashds7^M
From: <sip:IMSI12345678901235>;tag=4fa3^M
To: <sip:user1_public1@localhost>^M
CSeq: 1 REGISTER^M
Contact: <sip:[5555::aaa:bbb:ccc:ddd];comp=sigcomp>;expires=600000^M
Authorization: Digest, nonce="hexhexhexhexhexhexhexhexhexh1003", uri="sip:IMSI12345678904321", response="hexhexhexhexhexhexhe1004"^M
Max-forwards: 70^M
P-access-network-info: 3GPP-UTRAN-TDD; utran-cell-id-3gpp=234151D0FCE11^M
Supported: path^M
Content-Length: 0^M
^M
sipauthserve.cpp:-0-:processBuffer: imsi known, 2nd register
servershare.cpp:-0-:authenticate: ki unknown, no upstream server, sres not cached
servershare.cpp:-0-:authenticate: returning = 1
sipauthserve.cpp:-0-:prettyPrint: response:
SIP/2.0 200 OK^M
Via: SIP/2.0/UDP localhost:5063;branch=1;received=string_address@foo.bar^M
Via: SIP/2.0/UDP [5555::aaa:bbb:ccc:ddd];comp=sigcomp;branch=z9hG4bKnashds7^M
From: <sip:IMSI12345678901235>;tag=4fa3^M
To: <sip:user1_public1@localhost>^M
CSeq: 1 REGISTER^M
Contact: <sip:[5555::aaa:bbb:ccc:ddd];comp=sigcomp>;expires=600000^M
Authorization: Digest, nonce="hexhexhexhexhexhexhexhexhexh1003", uri="sip:IMSI12345678904321", response="hexhexhexhexhexhexhe1004"^M
Max-forwards: 70^M
P-access-network-info: 3GPP-UTRAN-TDD; utran-cell-id-3gpp=234151D0FCE11^M
Supported: path^M
Content-Length: 0^M
^M
sipauthserve.cpp:-0-:processBuffer:
----------------
sipauthserve.cpp:-0-:prettyPrint: request:
REGISTER sip:localhost SIP/2.0^M
Via: SIP/2.0/UDP [5555::aaa:bbb:ccc:ddd];comp=sigcomp;branch=z9hG4bKnashds7^M
From: <sip:EXIT>;tag=4fa3^M
To: <sip:EXIT>^M
CSeq: 1 REGISTER^M
Contact: <sip:[5555::aaa:bbb:ccc:ddd];comp=sigcomp>;expires=600000^M
Max-forwards: 70^M
P-access-network-info: 3GPP-UTRAN-TDD; utran-cell-id-3gpp=234151D0FCE11^M
Supported: path^M
Content-Length: 0^M
^M
IMSI12345678901231|||known|
IMSI12345678901232|hexhexhexhexhexhexhexhexhexh1002|||
IMSI12345678901234|||hexhexhexhexhexhexhexhexhexh1000|
IMSI12345678901235|hexhexhexhexhexhexhexhexhexh1003|hexh1005||
sipauthserve.cpp:-0-:prettyPrint: request:
REGISTER sip:localhost SIP/2.0^M
Via: SIP/2.0/UDP [5555::aaa:bbb:ccc:ddd];comp=sigcomp;branch=z9hG4bKnashds7^M
From: <sip:IMSI12345678901235>;tag=4fa3^M
To: <sip:user1_public1@localhost>^M
CSeq: 1 REGISTER^M
Contact: <sip:[5555::aaa:bbb:ccc:ddd];comp=sigcomp>;expires=600000^M
Authorization: Digest, nonce="hexhexhexhexhexhexhexhexhexh1003", uri="sip:IMSI12345678904321", response="hexhexhexhexhexhexhe1004"^M
Max-forwards: 70^M
P-access-network-info: 3GPP-UTRAN-TDD; utran-cell-id-3gpp=234151D0FCE11^M
Supported: path^M
Content-Length: 0^M
^M
sipauthserve.cpp:-0-:processBuffer: imsi known, 2nd register
servershare.cpp:-0-:authenticate: ki unknown, no upstream server, sres cached
servershare.cpp:-0-:authenticate: returning = 1
sipauthserve.cpp:-0-:prettyPrint: response:
SIP/2.0 200 OK^M
Via: SIP/2.0/UDP localhost:5063;branch=1;received=string_address@foo.bar^M
Via: SIP/2.0/UDP [5555::aaa:bbb:ccc:ddd];comp=sigcomp;branch=z9hG4bKnashds7^M
From: <sip:IMSI12345678901235>;tag=4fa3^M
To: <sip:user1_public1@localhost>^M
CSeq: 1 REGISTER^M
Contact: <sip:[5555::aaa:bbb:ccc:ddd];comp=sigcomp>;expires=600000^M
Authorization: Digest, nonce="hexhexhexhexhexhexhexhexhexh1003", uri="sip:IMSI12345678904321", response="hexhexhexhexhexhexhe1004"^M
Max-forwards: 70^M
P-access-network-info: 3GPP-UTRAN-TDD; utran-cell-id-3gpp=234151D0FCE11^M
Supported: path^M
Content-Length: 0^M
^M
sipauthserve.cpp:-0-:processBuffer:
----------------
sipauthserve.cpp:-0-:prettyPrint: request:
REGISTER sip:localhost SIP/2.0^M
Via: SIP/2.0/UDP [5555::aaa:bbb:ccc:ddd];comp=sigcomp;branch=z9hG4bKnashds7^M
From: <sip:EXIT>;tag=4fa3^M
To: <sip:EXIT>^M
CSeq: 1 REGISTER^M
Contact: <sip:[5555::aaa:bbb:ccc:ddd];comp=sigcomp>;expires=600000^M
Max-forwards: 70^M
P-access-network-info: 3GPP-UTRAN-TDD; utran-cell-id-3gpp=234151D0FCE11^M
Supported: path^M
Content-Length: 0^M
^M
IMSI12345678901231|||known|
IMSI12345678901232|hexhexhexhexhexhexhexhexhexh1002|||
IMSI12345678901234|||hexhexhexhexhexhexhexhexhexh1000|
IMSI12345678901235|hexhexhexhexhexhexhexhexhexh1003|hexh1005||
sipauthserve.cpp:-0-:prettyPrint: request:
REGISTER sip:localhost SIP/2.0^M
Via: SIP/2.0/UDP [5555::aaa:bbb:ccc:ddd];comp=sigcomp;branch=z9hG4bKnashds7^M
From: <sip:IMSI12345678901235>;tag=4fa3^M
To: <sip:user1_public1@localhost>^M
CSeq: 1 REGISTER^M
Contact: <sip:[5555::aaa:bbb:ccc:ddd];comp=sigcomp>;expires=600000^M
Authorization: Digest, nonce="hexhexhexhexhexhexhexhexhexh1006", uri="sip:IMSI12345678904321", response="hexhexhexhexhexhexhe1004"^M
Max-forwards: 70^M
P-access-network-info: 3GPP-UTRAN-TDD; utran-cell-id-3gpp=234151D0FCE11^M
Supported: path^M
Content-Length: 0^M
^M
sipauthserve.cpp:-0-:processBuffer: imsi known, 2nd register
servershare.cpp:-0-:authenticate: ki unknown, no upstream server, sres cached
servershare.cpp:-0-:authenticate: returning = 0
sipauthserve.cpp:-0-:prettyPrint: response:
SIP/2.0 401 Unauthorized^M
Via: SIP/2.0/UDP localhost:5063;branch=1;received=string_address@foo.bar^M
Via: SIP/2.0/UDP [5555::aaa:bbb:ccc:ddd];comp=sigcomp;branch=z9hG4bKnashds7^M
From: <sip:IMSI12345678901235>;tag=4fa3^M
To: <sip:user1_public1@localhost>^M
CSeq: 1 REGISTER^M
Contact: <sip:[5555::aaa:bbb:ccc:ddd];comp=sigcomp>;expires=600000^M
Authorization: Digest, nonce="hexhexhexhexhexhexhexhexhexh1006", uri="sip:IMSI12345678904321", response="hexhexhexhexhexhexhe1004"^M
Max-forwards: 70^M
P-access-network-info: 3GPP-UTRAN-TDD; utran-cell-id-3gpp=234151D0FCE11^M
Supported: path^M
Content-Length: 0^M
^M
sipauthserve.cpp:-0-:processBuffer:
----------------
sipauthserve.cpp:-0-:prettyPrint: request:
REGISTER sip:localhost SIP/2.0^M
Via: SIP/2.0/UDP [5555::aaa:bbb:ccc:ddd];comp=sigcomp;branch=z9hG4bKnashds7^M
From: <sip:EXIT>;tag=4fa3^M
To: <sip:EXIT>^M
CSeq: 1 REGISTER^M
Contact: <sip:[5555::aaa:bbb:ccc:ddd];comp=sigcomp>;expires=600000^M
Max-forwards: 70^M
P-access-network-info: 3GPP-UTRAN-TDD; utran-cell-id-3gpp=234151D0FCE11^M
Supported: path^M
Content-Length: 0^M
^M
IMSI12345678901231|||known|
IMSI12345678901232|hexhexhexhexhexhexhexhexhexh1002|||
IMSI12345678901234|||hexhexhexhexhexhexhexhexhexh1000|
IMSI12345678901235|hexhexhexhexhexhexhexhexhexh1003|hexh1005||
sipauthserve.cpp:-0-:prettyPrint: request:
REGISTER sip:localhost SIP/2.0^M
Via: SIP/2.0/UDP [5555::aaa:bbb:ccc:ddd];comp=sigcomp;branch=z9hG4bKnashds7^M
From: <sip:IMSI12345678901235>;tag=4fa3^M
To: <sip:user1_public1@localhost>^M
CSeq: 1 REGISTER^M
Contact: <sip:[5555::aaa:bbb:ccc:ddd];comp=sigcomp>;expires=600000^M
Authorization: Digest, nonce="hexhexhexhexhexhexhexhexhexh1003", uri="sip:IMSI12345678904321", response="hexhexhexhexhexhexhe1008"^M
Max-forwards: 70^M
P-access-network-info: 3GPP-UTRAN-TDD; utran-cell-id-3gpp=234151D0FCE11^M
Supported: path^M
Content-Length: 0^M
^M
sipauthserve.cpp:-0-:processBuffer: imsi known, 2nd register
servershare.cpp:-0-:authenticate: ki unknown, no upstream server, sres cached
servershare.cpp:-0-:authenticate: returning = 0
sipauthserve.cpp:-0-:prettyPrint: response:
SIP/2.0 401 Unauthorized^M
Via: SIP/2.0/UDP localhost:5063;branch=1;received=string_address@foo.bar^M
Via: SIP/2.0/UDP [5555::aaa:bbb:ccc:ddd];comp=sigcomp;branch=z9hG4bKnashds7^M
From: <sip:IMSI12345678901235>;tag=4fa3^M
To: <sip:user1_public1@localhost>^M
CSeq: 1 REGISTER^M
Contact: <sip:[5555::aaa:bbb:ccc:ddd];comp=sigcomp>;expires=600000^M
Authorization: Digest, nonce="hexhexhexhexhexhexhexhexhexh1003", uri="sip:IMSI12345678904321", response="hexhexhexhexhexhexhe1008"^M
Max-forwards: 70^M
P-access-network-info: 3GPP-UTRAN-TDD; utran-cell-id-3gpp=234151D0FCE11^M
Supported: path^M
Content-Length: 0^M
^M
sipauthserve.cpp:-0-:processBuffer:
----------------
sipauthserve.cpp:-0-:prettyPrint: request:
REGISTER sip:localhost SIP/2.0^M
Via: SIP/2.0/UDP [5555::aaa:bbb:ccc:ddd];comp=sigcomp;branch=z9hG4bKnashds7^M
From: <sip:EXIT>;tag=4fa3^M
To: <sip:EXIT>^M
CSeq: 1 REGISTER^M
Contact: <sip:[5555::aaa:bbb:ccc:ddd];comp=sigcomp>;expires=600000^M
Max-forwards: 70^M
P-access-network-info: 3GPP-UTRAN-TDD; utran-cell-id-3gpp=234151D0FCE11^M
Supported: path^M
Content-Length: 0^M
^M
IMSI12345678901231|||known|
IMSI12345678901232|hexhexhexhexhexhexhexhexhexh1002|||
IMSI12345678901234|||hexhexhexhexhexhexhexhexhexh1000|
IMSI12345678901235|hexhexhexhexhexhexhexhexhexh1003|hexh1005||
sipauthserve.cpp:-0-:prettyPrint: request:
REGISTER sip:localhost SIP/2.0^M
Via: SIP/2.0/UDP [5555::aaa:bbb:ccc:ddd];comp=sigcomp;branch=z9hG4bKnashds7^M
From: <sip:IMSI12345678901236>;tag=4fa3^M
To: <sip:user1_public1@localhost>^M
CSeq: 1 REGISTER^M
Contact: <sip:[5555::aaa:bbb:ccc:ddd];comp=sigcomp>;expires=600000^M
Authorization: Digest, nonce="342abcdef", uri="sip:IMSI12345678904321", response="283742876"^M
Max-forwards: 70^M
P-access-network-info: 3GPP-UTRAN-TDD; utran-cell-id-3gpp=234151D0FCE11^M
Supported: path^M
Content-Length: 0^M
^M
sipauthserve.cpp:-0-:processBuffer: imsi unknown
sipauthserve.cpp:-0-:prettyPrint: response:
SIP/2.0 404 IMSI Not Found^M
Via: SIP/2.0/UDP localhost:5063;branch=1;received=string_address@foo.bar^M
Via: SIP/2.0/UDP [5555::aaa:bbb:ccc:ddd];comp=sigcomp;branch=z9hG4bKnashds7^M
From: <sip:IMSI12345678901236>;tag=4fa3^M
To: <sip:user1_public1@localhost>^M
CSeq: 1 REGISTER^M
Contact: <sip:[5555::aaa:bbb:ccc:ddd];comp=sigcomp>;expires=600000^M
Authorization: Digest, nonce="342abcdef", uri="sip:IMSI12345678904321", response="283742876"^M
Max-forwards: 70^M
P-access-network-info: 3GPP-UTRAN-TDD; utran-cell-id-3gpp=234151D0FCE11^M
Supported: path^M
Content-Length: 0^M
^M
sipauthserve.cpp:-0-:processBuffer:
----------------
sipauthserve.cpp:-0-:prettyPrint: request:
REGISTER sip:localhost SIP/2.0^M
Via: SIP/2.0/UDP [5555::aaa:bbb:ccc:ddd];comp=sigcomp;branch=z9hG4bKnashds7^M
From: <sip:EXIT>;tag=4fa3^M
To: <sip:EXIT>^M
CSeq: 1 REGISTER^M
Contact: <sip:[5555::aaa:bbb:ccc:ddd];comp=sigcomp>;expires=600000^M
Max-forwards: 70^M
P-access-network-info: 3GPP-UTRAN-TDD; utran-cell-id-3gpp=234151D0FCE11^M
Supported: path^M
Content-Length: 0^M
^M
IMSI12345678901231|||known|
IMSI12345678901232|hexhexhexhexhexhexhexhexhexh1002|||
IMSI12345678901234|||hexhexhexhexhexhexhexhexhexh1000|
IMSI12345678901235|hexhexhexhexhexhexhexhexhexh1003|hexh1005||

View File

@ -0,0 +1 @@
select name, rand, sres, ki, kc from sip_buddies;

View File

@ -0,0 +1,10 @@
REGISTER sip:localhost SIP/2.0
Via: SIP/2.0/UDP [5555::aaa:bbb:ccc:ddd]; comp=sigcomp;branch=z9hG4bKnashds7
Max-Forwards: 70
P-Access-Network-Info: 3GPP-UTRAN-TDD; utran-cell-id-3gpp=234151D0FCE11
From: <sip:IMSI12345678901231>;tag=4fa3
To: <sip:user1_public1@localhost>
Contact: <sip:[5555::aaa:bbb:ccc:ddd];comp=sigcomp>;expires=600000
CSeq: 1 REGISTER
Supported: path
Content-Length: 0

View File

@ -0,0 +1,10 @@
REGISTER sip:localhost SIP/2.0
Via: SIP/2.0/UDP [5555::aaa:bbb:ccc:ddd]; comp=sigcomp;branch=z9hG4bKnashds7
Max-Forwards: 70
P-Access-Network-Info: 3GPP-UTRAN-TDD; utran-cell-id-3gpp=234151D0FCE11
From: <sip:IMSI12345678901232>;tag=4fa3
To: <sip:user1_public1@localhost>
Contact: <sip:[5555::aaa:bbb:ccc:ddd];comp=sigcomp>;expires=600000
CSeq: 1 REGISTER
Supported: path
Content-Length: 0

View File

@ -0,0 +1,10 @@
REGISTER sip:localhost SIP/2.0
Via: SIP/2.0/UDP [5555::aaa:bbb:ccc:ddd]; comp=sigcomp;branch=z9hG4bKnashds7
Max-Forwards: 70
P-Access-Network-Info: 3GPP-UTRAN-TDD; utran-cell-id-3gpp=234151D0FCE11
From: <sip:IMSI12345678901233>;tag=4fa3
To: <sip:user1_public1@localhost>
Contact: <sip:[5555::aaa:bbb:ccc:ddd];comp=sigcomp>;expires=600000
CSeq: 1 REGISTER
Supported: path
Content-Length: 0

View File

@ -0,0 +1,11 @@
REGISTER sip:localhost SIP/2.0
Via: SIP/2.0/UDP [5555::aaa:bbb:ccc:ddd]; comp=sigcomp;branch=z9hG4bKnashds7
Max-Forwards: 70
P-Access-Network-Info: 3GPP-UTRAN-TDD; utran-cell-id-3gpp=234151D0FCE11
From: <sip:IMSI12345678901234>;tag=4fa3
To: <sip:user1_public1@localhost>
Contact: <sip:[5555::aaa:bbb:ccc:ddd];comp=sigcomp>;expires=600000
Authorization: Digest nonce="d76fe9a5839089a2ebeb269b46bf46ff", uri="sip:IMSI12345678904321", response="726259AF43D0387D6BDAFC00"
CSeq: 1 REGISTER
Supported: path
Content-Length: 0

View File

@ -0,0 +1,11 @@
REGISTER sip:localhost SIP/2.0
Via: SIP/2.0/UDP [5555::aaa:bbb:ccc:ddd]; comp=sigcomp;branch=z9hG4bKnashds7
Max-Forwards: 70
P-Access-Network-Info: 3GPP-UTRAN-TDD; utran-cell-id-3gpp=234151D0FCE11
From: <sip:IMSI12345678901234>;tag=4fa3
To: <sip:user1_public1@localhost>
Contact: <sip:[5555::aaa:bbb:ccc:ddd];comp=sigcomp>;expires=600000
Authorization: Digest nonce="F76fe9a5839089a2ebeb269b46bf46ff", uri="sip:IMSI12345678904321", response="726259AF43D0387D6BDAFC00"
CSeq: 1 REGISTER
Supported: path
Content-Length: 0

View File

@ -0,0 +1,11 @@
REGISTER sip:localhost SIP/2.0
Via: SIP/2.0/UDP [5555::aaa:bbb:ccc:ddd]; comp=sigcomp;branch=z9hG4bKnashds7
Max-Forwards: 70
P-Access-Network-Info: 3GPP-UTRAN-TDD; utran-cell-id-3gpp=234151D0FCE11
From: <sip:IMSI12345678901234>;tag=4fa3
To: <sip:user1_public1@localhost>
Contact: <sip:[5555::aaa:bbb:ccc:ddd];comp=sigcomp>;expires=600000
Authorization: Digest nonce="d76fe9a5839089a2ebeb269b46bf46ff", uri="sip:IMSI12345678904321", response="F26259AF43D0387D6BDAFC00"
CSeq: 1 REGISTER
Supported: path
Content-Length: 0

View File

@ -0,0 +1,11 @@
REGISTER sip:localhost SIP/2.0
Via: SIP/2.0/UDP [5555::aaa:bbb:ccc:ddd]; comp=sigcomp;branch=z9hG4bKnashds7
Max-Forwards: 70
P-Access-Network-Info: 3GPP-UTRAN-TDD; utran-cell-id-3gpp=234151D0FCE11
From: <sip:IMSI12345678901235>;tag=4fa3
To: <sip:user1_public1@localhost>
Contact: <sip:[5555::aaa:bbb:ccc:ddd];comp=sigcomp>;expires=600000
Authorization: Digest nonce="d76fe9a5839089a2ebeb269b46bf46ff", uri="sip:IMSI12345678904321", response="726259AF43D0387D6BDAFC00"
CSeq: 1 REGISTER
Supported: path
Content-Length: 0

View File

@ -0,0 +1,11 @@
REGISTER sip:localhost SIP/2.0
Via: SIP/2.0/UDP [5555::aaa:bbb:ccc:ddd]; comp=sigcomp;branch=z9hG4bKnashds7
Max-Forwards: 70
P-Access-Network-Info: 3GPP-UTRAN-TDD; utran-cell-id-3gpp=234151D0FCE11
From: <sip:IMSI12345678901235>;tag=4fa3
To: <sip:user1_public1@localhost>
Contact: <sip:[5555::aaa:bbb:ccc:ddd];comp=sigcomp>;expires=600000
Authorization: Digest nonce="F76fe9a5839089a2ebeb269b46bf46ff", uri="sip:IMSI12345678904321", response="726259AF43D0387D6BDAFC00"
CSeq: 1 REGISTER
Supported: path
Content-Length: 0

View File

@ -0,0 +1,11 @@
REGISTER sip:localhost SIP/2.0
Via: SIP/2.0/UDP [5555::aaa:bbb:ccc:ddd]; comp=sigcomp;branch=z9hG4bKnashds7
Max-Forwards: 70
P-Access-Network-Info: 3GPP-UTRAN-TDD; utran-cell-id-3gpp=234151D0FCE11
From: <sip:IMSI12345678901235>;tag=4fa3
To: <sip:user1_public1@localhost>
Contact: <sip:[5555::aaa:bbb:ccc:ddd];comp=sigcomp>;expires=600000
Authorization: Digest nonce="d76fe9a5839089a2ebeb269b46bf46ff", uri="sip:IMSI12345678904321", response="F26259AF43D0387D6BDAFC00"
CSeq: 1 REGISTER
Supported: path
Content-Length: 0

View File

@ -0,0 +1,11 @@
REGISTER sip:localhost SIP/2.0
Via: SIP/2.0/UDP [5555::aaa:bbb:ccc:ddd]; comp=sigcomp;branch=z9hG4bKnashds7
Max-Forwards: 70
P-Access-Network-Info: 3GPP-UTRAN-TDD; utran-cell-id-3gpp=234151D0FCE11
From: <sip:IMSI12345678901236>;tag=4fa3
To: <sip:user1_public1@localhost>
Contact: <sip:[5555::aaa:bbb:ccc:ddd];comp=sigcomp>;expires=600000
Authorization: Digest nonce="342abcdef", uri="sip:IMSI12345678904321", response="283742876"
CSeq: 1 REGISTER
Supported: path
Content-Length: 0

126
test.sipauthserve/runtest Executable file
View File

@ -0,0 +1,126 @@
#!/bin/bash
configdb=/etc/OpenBTS/OpenBTS.db
srdb=sr.db
# start with a known state in DBs
rm -f $configdb $srdb
# initialize the config db
sqlite3 $configdb < sipauthserve.db.init
# initialize the SR db
sqlite3 $srdb < sr.db.init
chmod 666 $srdb
# initialize the output file
date > output.got
# look at database
sqlite3 $srdb < ./query.sql >> output.got
# Each test below enters a mark in the syslog so we can extract only
# the log entries for that test.
# Then it starts the sip authentication server.
# Then it sends the test message to the sip authentication server.
# Then it stops the sip authentication server.
# Then it extracts the test's log entries.
# Then it dumps the SR database.
# rand, imsi known, ki known
logger -plocal7.Debug dwb syslog mark
../sipauthserve &
./usender.pl < register1.txt
./usender.pl < exit.txt
../syslogextractor >> output.got
sqlite3 $srdb < ./query.sql >> output.got
# rand, imsi known, ki unknown, rand not cached
logger -plocal7.Debug dwb syslog mark
../sipauthserve &
./usender.pl < register2.txt
./usender.pl < exit.txt
../syslogextractor >> output.got
sqlite3 $srdb < ./query.sql >> output.got
# rand, imsi known, ki unknown, rand cached
logger -plocal7.Debug dwb syslog mark
../sipauthserve &
./usender.pl < register2.txt
./usender.pl < exit.txt
../syslogextractor >> output.got
sqlite3 $srdb < ./query.sql >> output.got
# rand, imsi unknown
logger -plocal7.Debug dwb syslog mark
../sipauthserve &
./usender.pl < register3.txt
./usender.pl < exit.txt
../syslogextractor >> output.got
sqlite3 $srdb < ./query.sql >> output.got
# auth, imsi known, values good
logger -plocal7.Debug dwb syslog mark
../sipauthserve &
./usender.pl < register4.txt
./usender.pl < exit.txt
../syslogextractor >> output.got
sqlite3 $srdb < ./query.sql >> output.got
# auth, imsi known, values bad
logger -plocal7.Debug dwb syslog mark
../sipauthserve &
./usender.pl < register4a.txt
./usender.pl < exit.txt
../syslogextractor >> output.got
sqlite3 $srdb < ./query.sql >> output.got
# auth, imsi known, values bad
logger -plocal7.Debug dwb syslog mark
../sipauthserve &
./usender.pl < register4b.txt
./usender.pl < exit.txt
../syslogextractor >> output.got
sqlite3 $srdb < ./query.sql >> output.got
# auth, imsi known, ki unknown, sres not cached
logger -plocal7.Debug dwb syslog mark
../sipauthserve &
./usender.pl < register5.txt
./usender.pl < exit.txt
../syslogextractor >> output.got
sqlite3 $srdb < ./query.sql >> output.got
# auth, imsi known, ki unknown, sres cached, values good
logger -plocal7.Debug dwb syslog mark
../sipauthserve &
./usender.pl < register5.txt
./usender.pl < exit.txt
../syslogextractor >> output.got
sqlite3 $srdb < ./query.sql >> output.got
# auth, imsi known, ki unknown, sres cached, values bad
logger -plocal7.Debug dwb syslog mark
../sipauthserve &
./usender.pl < register5a.txt
./usender.pl < exit.txt
../syslogextractor >> output.got
sqlite3 $srdb < ./query.sql >> output.got
# auth, imsi known, ki unknown, sres cached, values bad
logger -plocal7.Debug dwb syslog mark
../sipauthserve &
./usender.pl < register5b.txt
./usender.pl < exit.txt
../syslogextractor >> output.got
sqlite3 $srdb < ./query.sql >> output.got
# auth, imsi unknown
logger -plocal7.Debug dwb syslog mark
../sipauthserve &
./usender.pl < register6.txt
./usender.pl < exit.txt
../syslogextractor >> output.got
sqlite3 $srdb < ./query.sql >> output.got
# normalize the output file for diffing
mv output.got ootput.got
../hexmapper ootput.got > output.got
diff output.exp output.got
exit 0

View File

@ -0,0 +1,34 @@
BEGIN TRANSACTION;
CREATE TABLE CONFIG ( KEYSTRING TEXT UNIQUE NOT NULL, VALUESTRING TEXT, STATIC INTEGER DEFAULT 0, OPTIONAL INTEGER DEFAULT 0, COMMENTS TEXT DEFAULT '');
INSERT INTO "CONFIG" VALUES('SubscriberRegistry.db','sr.db',0,0,'The location of the sqlite3 database holding the subscriber registry.');
INSERT INTO "CONFIG" VALUES('SubscriberRegistry.A3A8','../comp128',0,0,'');
INSERT INTO "CONFIG" VALUES('SubscriberRegistry.UpstreamServer','',0,0,'');
INSERT INTO "CONFIG" VALUES('Log.Level','INFO',0,0,'');
INSERT INTO "CONFIG" VALUES('Log.Level.smcommands.cpp','INFO',0,0,'');
INSERT INTO "CONFIG" VALUES('savefile','savedqueue.txt',0,0,'');
INSERT INTO "CONFIG" VALUES('SIP.myPort','5063',0,0,'');
INSERT INTO "CONFIG" VALUES('Debug.print_as_we_validate','',0,0,'');
INSERT INTO "CONFIG" VALUES('$optional','Debug.print_as_we_validate',0,0,'');
INSERT INTO "CONFIG" VALUES('BounceMessage.IMSILookupFailed','Cannot determine return address; bouncing message. Text your phone number to 101 to register and try again.',0,0,'');
INSERT INTO "CONFIG" VALUES('BounceMessage.NotRegistered','Phone not registered here.',0,0,'');
INSERT INTO "CONFIG" VALUES('SC.Register.Code','101',0,0,'');
INSERT INTO "CONFIG" VALUES('SC.Register.Msg.WelcomeA','Hello',0,0,'');
INSERT INTO "CONFIG" VALUES('SC.Register.Msg.WelcomeB','! Text to 411 for system status.',0,0,'');
INSERT INTO "CONFIG" VALUES('SC.Register.Msg.AlreadyA','Your phone is already registered as',0,0,'');
INSERT INTO "CONFIG" VALUES('SC.Register.Msg.AlreadyB','.',0,0,'');
INSERT INTO "CONFIG" VALUES('SC.Register.Msg.TakenA','The phone number',0,0,'');
INSERT INTO "CONFIG" VALUES('SC.Register.Msg.TakenB','is already in use. Try another, then call that one to talk to whoever took yours.',0,0,'');
INSERT INTO "CONFIG" VALUES('SC.Register.Msg.ErrorA','Error in assigning',0,0,'');
INSERT INTO "CONFIG" VALUES('SC.Register.Msg.ErrorB','to IMSI',0,0,'');
INSERT INTO "CONFIG" VALUES('SC.Register.Digits.Max','10',0,0,'');
INSERT INTO "CONFIG" VALUES('SC.Register.Digits.Min','7',0,0,'');
INSERT INTO "CONFIG" VALUES('SC.Register.Digits.Override','',0,0,'');
INSERT INTO "CONFIG" VALUES('SC.Info.Code','411',0,0,'');
INSERT INTO "CONFIG" VALUES('SC.DebugDump.Code','2336',0,0,'');
INSERT INTO "CONFIG" VALUES('SC.QuickChk.Code','2337',0,0,'');
INSERT INTO "CONFIG" VALUES('SC.ZapQueued.Code','2338',0,0,'');
INSERT INTO "CONFIG" VALUES('SC.ZapQueued.Password','6000',0,0,'');
INSERT INTO "CONFIG" VALUES('SC.WhiplashQuit.Code','314158',0,0,'');
INSERT INTO "CONFIG" VALUES('SC.WhiplashQuit.Password','Snidely',0,0,'');
INSERT INTO "CONFIG" VALUES('SC.WhiplashQuit.SaveFile','testsave.txt',0,0,'');
COMMIT;

View File

@ -1,17 +1,17 @@
PRAGMA foreign_keys=OFF;
PRAGMA journal_mode=WAL;
BEGIN TRANSACTION;
CREATE TABLE IF NOT EXISTS dialdata_table (
CREATE TABLE dialdata_table (
id INTEGER,
exten VARCHAR(40) NOT NULL DEFAULT '',
dial VARCHAR(128) NOT NULL DEFAULT '',
PRIMARY KEY (id)
);
CREATE TABLE IF NOT EXISTS 'sip_buddies'
INSERT INTO "dialdata_table" VALUES(1,'1000','1000');
INSERT INTO "dialdata_table" VALUES(2,'1001','1001');
INSERT INTO "dialdata_table" VALUES(3,'clid1','imsi1');
CREATE TABLE 'sip_buddies'
(
id integer,
name VARCHAR(80) not null,
name VARCHAR(80) unique not null,
context VARCHAR(80),
callingpres VARCHAR(30) DEFAULT 'allowed_not_screened',
deny VARCHAR(95),
@ -20,7 +20,7 @@ secret VARCHAR(80),
md5secret VARCHAR(80),
remotesecret VARCHAR(250),
transport VARCHAR(10),
host VARCHAR(31) not null,
host VARCHAR(31) DEFAULT '' not null,
nat VARCHAR(5) DEFAULT 'no' not null,
type VARCHAR(10) DEFAULT 'friend' not null,
accountcode VARCHAR(20),
@ -87,26 +87,16 @@ mask VARCHAR(95),
musiconhold VARCHAR(100),
restrictcid CHAR(3),
calllimit int(5),
WhiteListFlag timestamp not null default '0',
WhiteListCode varchar(8) not null default '0',
rand varchar(33) default '',
sres varchar(33) default '',
ki varchar(33) default '',
kc varchar(33) default '',
prepaid int(1) DEFAULT 0 not null,
account_balance int(9) default 0 not null,
RRLPSupported int(1) default 1 not null,
hardware VARCHAR(20),
regTime INTEGER default 0 NOT NULL,
a3_a8 varchar(45) default NULL,
rand varchar(33) default '',
sres varchar(33) default '',
ki varchar(33) default '',
kc varchar(33) default '',
primary key(id)
)
;
);
CREATE TABLE IF NOT EXISTS 'rates'
(
service varchar(30) not null,
rate integer not null
)
;
COMMIT;
insert into sip_buddies (name,rand,sres,ki,kc) values ('IMSI12345678901231','','','known','');
insert into sip_buddies (name,rand,sres,ki,kc) values ('IMSI12345678901232','','','','');
insert into sip_buddies (name,rand,sres,ki,kc) values ('IMSI12345678901234','','','48091124c1155bd95c6f1860dc66ce92','');
insert into sip_buddies (name,rand,sres,ki,kc) values ('IMSI12345678901235','','','','');
COMMIT;

31
test.sipauthserve/usender.pl Executable file
View File

@ -0,0 +1,31 @@
#!/usr/bin/perl -w
$|++;
use strict;
use IO::Socket;
my($host) = '127.0.0.1';
my($port) = '5063';
my($datagram) = "";
while (<>) {
$datagram .= $_;
}
my $message = IO::Socket::INET->new(Proto=>"udp",
PeerPort=>$port,PeerAddr=>$host)
or die "Can't make UDP socket ($host:$port): $@";
# printf "sending $datagram";
$message->send($datagram);
# MESSAGE sip:user2@domain.com SIP/2.0
# Via: SIP/2.0/TCP user1pc.domain.com;branch=z9hG4bK776sgdkse
# Max-Forwards: 70
# From: sip:user1@domain.com;tag=49583
# To: sip:user2@domain.com
# Call-ID: asd88asd77a@1.2.3.4
# CSeq: 1 MESSAGE
# Content-Type: text/plain
# Content-Length: 18
#
# Watson, come here.

1027
test.srmanager/output.exp Normal file

File diff suppressed because it is too large Load Diff

2
test.srmanager/query.sql Normal file
View File

@ -0,0 +1,2 @@
select name, username, type, context, host from sip_buddies;
select exten, dial from dialdata_table;

90
test.srmanager/runtest Executable file
View File

@ -0,0 +1,90 @@
#!/bin/bash
# start with a known state in DBs
rm -f /etc/OpenBTS/OpenBTS.db test.db
# initialize the config db
sqlite3 /etc/OpenBTS/OpenBTS.db < srmanager.db.init
chmod 666 /etc/OpenBTS/OpenBTS.db
# initialize the SR db
sqlite3 test.db < test.db.init
# initialize the output file
date > output.got
# Each test below enters a mark in the syslog so we can extract only
# the log entries for that test.
# Then it sets the environment variables (and stdin for POST) to duplicate
# http state, then it runs the test.
# Then it extracts the test's log entries.
# On some it then dumps the SR database.
# empty http get
logger -plocal7.Debug dwb syslog mark
REQUEST_METHOD=GET;
export REQUEST_METHOD
QUERY_STRING=
export QUERY_STRING
../srmanager.cgi >> output.got
../syslogextractor >> output.got
# http get for main page
logger -plocal7.Debug dwb syslog mark
REQUEST_METHOD=GET;
export REQUEST_METHOD
QUERY_STRING=what=Main
export QUERY_STRING
../srmanager.cgi >> output.got
../syslogextractor >> output.got
# empty http post
logger -plocal7.Debug dwb syslog mark
REQUEST_METHOD=POST;
export REQUEST_METHOD
CONTENT_LENGTH=0
export CONTENT_LENGTH
echo '' | ../srmanager.cgi >> output.got
../syslogextractor >> output.got
# http post for main page
logger -plocal7.Debug dwb syslog mark
REQUEST_METHOD=POST;
export REQUEST_METHOD
CONTENT_LENGTH=9
export CONTENT_LENGTH
echo 'what=Main' | ../srmanager.cgi >> output.got
../syslogextractor >> output.got
# http post for add
logger -plocal7.Debug dwb syslog mark
REQUEST_METHOD=POST;
export REQUEST_METHOD
CONTENT_LENGTH=55
export CONTENT_LENGTH
echo 'name=a&username=b&type=c&context=d&host=e&id=0&what=Add' | ../srmanager.cgi >> output.got
../syslogextractor >> output.got
sqlite3 test.db < ./query.sql >> output.got
# http post for delete
logger -plocal7.Debug dwb syslog mark
REQUEST_METHOD=POST;
export REQUEST_METHOD
CONTENT_LENGTH=58
export CONTENT_LENGTH
echo 'name=a&username=b&type=c&context=d&host=e&id=9&what=Delete' | ../srmanager.cgi >> output.got
../syslogextractor >> output.got
sqlite3 test.db < ./query.sql >> output.got
# http post for update
logger -plocal7.Debug dwb syslog mark
REQUEST_METHOD=POST;
export REQUEST_METHOD
CONTENT_LENGTH=35
export CONTENT_LENGTH
echo 'exten=qrs&dial=tuv&id=1&what=Update' | ../srmanager.cgi >> output.got
../syslogextractor >> output.got
sqlite3 test.db < ./query.sql >> output.got
# normalize the output file for diffing
mv output.got ootput.got
../hexmapper ootput.got > output.got
diff output.exp output.got
exit 0

View File

@ -0,0 +1,9 @@
BEGIN TRANSACTION;
CREATE TABLE CONFIG ( KEYSTRING TEXT UNIQUE NOT NULL, VALUESTRING TEXT, STATIC INTEGER DEFAULT 0, OPTIONAL INTEGER DEFAULT 0, COMMENTS TEXT DEFAULT '');
INSERT INTO "CONFIG" VALUES('Log.Level','DEBUG',0,0,'');
INSERT INTO "CONFIG" VALUES('SubscriberRegistry.db','test.db',0,0,'');
INSERT INTO "CONFIG" VALUES('SubscriberRegistry.Manager.VisibleColumns','name username type context host',0,0,'');
INSERT INTO "CONFIG" VALUES('SubscriberRegistry.Manager.Url','http://localhost/~doug/foo.cgi',0,0,'');
INSERT INTO "CONFIG" VALUES('SubscriberRegistry.Manager.Title','Some Title',0,0,'');
COMMIT;

102
test.srmanager/test.db.init Normal file
View File

@ -0,0 +1,102 @@
BEGIN TRANSACTION;
CREATE TABLE dialdata_table (
id INTEGER,
exten VARCHAR(40) NOT NULL DEFAULT '',
dial VARCHAR(128) NOT NULL DEFAULT '',
PRIMARY KEY (id)
);
INSERT INTO "dialdata_table" VALUES(1,'1000','1000');
INSERT INTO "dialdata_table" VALUES(2,'1001','1001');
CREATE TABLE 'sip_buddies'
(
id integer,
name VARCHAR(80) unique not null,
context VARCHAR(80),
callingpres VARCHAR(30) DEFAULT 'allowed_not_screened',
deny VARCHAR(95),
permit VARCHAR(95),
secret VARCHAR(80),
md5secret VARCHAR(80),
remotesecret VARCHAR(250),
transport VARCHAR(10),
host VARCHAR(31) DEFAULT '' not null,
nat VARCHAR(5) DEFAULT 'no' not null,
type VARCHAR(10) DEFAULT 'friend' not null,
accountcode VARCHAR(20),
amaflags VARCHAR(13),
callgroup VARCHAR(10),
callerid VARCHAR(80),
defaultip VARCHAR(40) DEFAULT '0.0.0.0',
dtmfmode VARCHAR(7) DEFAULT 'rfc2833',
fromuser VARCHAR(80),
fromdomain VARCHAR(80),
insecure VARCHAR(4),
language CHAR(2),
mailbox VARCHAR(50),
pickupgroup VARCHAR(10),
qualify CHAR(3),
regexten VARCHAR(80),
rtptimeout CHAR(3),
rtpholdtimeout CHAR(3),
setvar VARCHAR(100),
disallow VARCHAR(100) DEFAULT 'all',
allow VARCHAR(100) DEFAULT 'ulaw' not null,
fullcontact VARCHAR(80),
ipaddr VARCHAR(40),
port int(5) DEFAULT 0,
username VARCHAR(80),
defaultuser VARCHAR(80),
subscribecontext VARCHAR(80),
directmedia VARCHAR(3),
trustrpid VARCHAR(3),
sendrpid VARCHAR(3),
progressinband VARCHAR(5),
promiscredir VARCHAR(3),
useclientcode VARCHAR(3),
callcounter VARCHAR(3),
busylevel int(11),
allowoverlap VARCHAR(3) DEFAULT 'yes',
allowsubscribe VARCHAR(3) DEFAULT 'yes',
allowtransfer VARCHAR(3) DEFAULT 'yes',
ignoresdpversion VARCHAR(3) DEFAULT 'no',
template VARCHAR(100),
videosupport VARCHAR(6) DEFAULT 'no',
maxcallbitrate int(11),
rfc2833compensate VARCHAR(3) DEFAULT 'yes',
'session-timers' VARCHAR(10) DEFAULT 'accept',
'session-expires' int(6) DEFAULT 1800,
'session-minse' int(6) DEFAULT 90,
'session-refresher' VARCHAR(3) DEFAULT 'uas',
t38pt_usertpsource VARCHAR(3),
outboundproxy VARCHAR(250),
callbackextension VARCHAR(250),
registertrying VARCHAR(3) DEFAULT 'yes',
timert1 int(6) DEFAULT 500,
timerb int(9),
qualifyfreq int(6) DEFAULT 120,
contactpermit VARCHAR(250),
contactdeny VARCHAR(250),
lastms int(11) DEFAULT 0 not null,
regserver VARCHAR(100),
regseconds int(11) DEFAULT 0 not null,
useragent VARCHAR(100),
cancallforward CHAR(3) DEFAULT 'yes' not null,
canreinvite CHAR(3) DEFAULT 'yes' not null,
mask VARCHAR(95),
musiconhold VARCHAR(100),
restrictcid CHAR(3),
calllimit int(5),
ki VARCHAR(32) DEFAULT '' not null,
rand VARCHAR(32) DEFAULT '' not null,
sres VARCHAR(32) DEFAULT '' not null,
primary key(id)
);
INSERT INTO "sip_buddies" VALUES(1,'1000','phones','allowed_not_screened',NULL,NULL,NULL,NULL,NULL,NULL,'dynamic','no','friend',NULL,NULL,NULL,NULL,'0.0.0.0','rfc2833',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'all','ulaw',NULL,NULL,0,'1000',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'yes','yes','yes','no',NULL,'no',NULL,'yes','accept',1800,90,'uas',NULL,NULL,NULL,'yes',500,NULL,120,NULL,NULL,0,NULL,0,NULL,'yes','yes',NULL,NULL,NULL,NULL,'','','');
INSERT INTO "sip_buddies" VALUES(2,'1001','phones','allowed_not_screened',NULL,NULL,NULL,NULL,NULL,NULL,'dynamic','no','friend',NULL,NULL,NULL,NULL,'0.0.0.0','rfc2833',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'all','ulaw',NULL,NULL,0,'1001',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'yes','yes','yes','no',NULL,'no',NULL,'yes','accept',1800,90,'uas',NULL,NULL,NULL,'yes',500,NULL,120,NULL,NULL,0,NULL,0,NULL,'yes','yes',NULL,NULL,NULL,NULL,'','','');
INSERT INTO "sip_buddies" VALUES(3,'imsi2',NULL,'allowed_not_screened',NULL,NULL,NULL,NULL,NULL,NULL,'','no','friend',NULL,NULL,NULL,NULL,'0.0.0.0','rfc2833',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'all','ulaw',NULL,'imsi2ipaddr',0,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'yes','yes','yes','no',NULL,'no',NULL,'yes','accept',1800,90,'uas',NULL,NULL,NULL,'yes',500,NULL,120,NULL,NULL,0,NULL,0,NULL,'yes','yes',NULL,NULL,NULL,NULL,'','','');
INSERT INTO "sip_buddies" VALUES(4,'imsi_r1',NULL,'allowed_not_screened',NULL,NULL,NULL,NULL,NULL,NULL,'','no','friend',NULL,NULL,NULL,NULL,'0.0.0.0','rfc2833',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'all','ulaw',NULL,NULL,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'yes','yes','yes','no',NULL,'no',NULL,'yes','accept',1800,90,'uas',NULL,NULL,NULL,'yes',500,NULL,120,NULL,NULL,0,NULL,0,NULL,'yes','yes',NULL,NULL,NULL,NULL,'','','');
INSERT INTO "sip_buddies" VALUES(5,'imsi_r2',NULL,'allowed_not_screened',NULL,NULL,NULL,NULL,NULL,NULL,'','no','friend',NULL,NULL,NULL,NULL,'0.0.0.0','rfc2833',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'all','ulaw',NULL,NULL,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'yes','yes','yes','no',NULL,'no',NULL,'yes','accept',1800,90,'uas',NULL,NULL,NULL,'yes',500,NULL,120,NULL,NULL,0,NULL,0,NULL,'yes','yes',NULL,NULL,NULL,NULL,'','12345678901234567890123456789012','');
INSERT INTO "sip_buddies" VALUES(6,'imsi_a1',NULL,'allowed_not_screened',NULL,NULL,NULL,NULL,NULL,NULL,'','no','friend',NULL,NULL,NULL,NULL,'0.0.0.0','rfc2833',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'all','ulaw',NULL,NULL,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'yes','yes','yes','no',NULL,'no',NULL,'yes','accept',1800,90,'uas',NULL,NULL,NULL,'yes',500,NULL,120,NULL,NULL,0,NULL,0,NULL,'yes','yes',NULL,NULL,NULL,NULL,'7f4d7fbff290e20e60466bc7b5b08e4b','','');
INSERT INTO "sip_buddies" VALUES(7,'imsi_a2',NULL,'allowed_not_screened',NULL,NULL,NULL,NULL,NULL,NULL,'','no','friend',NULL,NULL,NULL,NULL,'0.0.0.0','rfc2833',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'all','ulaw',NULL,NULL,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'yes','yes','yes','no',NULL,'no',NULL,'yes','accept',1800,90,'uas',NULL,NULL,NULL,'yes',500,NULL,120,NULL,NULL,0,NULL,0,NULL,'yes','yes',NULL,NULL,NULL,NULL,'','123','456');
INSERT INTO "sip_buddies" VALUES(8,'imsi_a3',NULL,'allowed_not_screened',NULL,NULL,NULL,NULL,NULL,NULL,'','no','friend',NULL,NULL,NULL,NULL,'0.0.0.0','rfc2833',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'all','ulaw',NULL,NULL,0,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'yes','yes','yes','no',NULL,'no',NULL,'yes','accept',1800,90,'uas',NULL,NULL,NULL,'yes',500,NULL,120,NULL,NULL,0,NULL,0,NULL,'yes','yes',NULL,NULL,NULL,NULL,'','123456789012345678901234567890a3','1234567890123456789012a3');
COMMIT;

View File

@ -0,0 +1,133 @@
Fri Mar 18 16:47:36 PDT 2011
Content-Type: text
servershare.cpp:-0-:decodeQuery: REQUEST_METHOD = GET
servershare.cpp:-0-:decodeQuery: QUERY_STRING = req=sql&stmts=insert into sip_buddies (name) values ("newname")
subscriberserver.cpp:-0-:logQuery: query
subscriberserver.cpp:-0-:logQuery: req -> sql
subscriberserver.cpp:-0-:logQuery: stmts -> insert into sip_buddies (name) values ("newname")
subscriberserver.cpp:-0-:logResponse: response
IMSI12345678901231|hexhexhexhexhexhexhexhexhexh1000|||
IMSI12345678901232||||
IMSI12345678901233|||hexhexhexhexhexhexhexhexhexh1000|
newname||||
Content-Type: text
res=IMSI12345678901232
servershare.cpp:-0-:decodeQuery: REQUEST_METHOD = GET
servershare.cpp:-0-:decodeQuery: QUERY_STRING = req=sql&stmts=select name from sip_buddies where id=2
subscriberserver.cpp:-0-:logQuery: query
subscriberserver.cpp:-0-:logQuery: req -> sql
subscriberserver.cpp:-0-:logQuery: stmts -> select name from sip_buddies where id=2
subscriberserver.cpp:-0-:logResponse: response
subscriberserver.cpp:-0-:logResponse: res=IMSI12345678901232
IMSI12345678901231|hexhexhexhexhexhexhexhexhexh1000|||
IMSI12345678901232||||
IMSI12345678901233|||hexhexhexhexhexhexhexhexhexh1000|
newname||||
Content-Type: text
rand=hexhexhexhexhexhexhexhexhexh1000
imsi=IMSI12345678901231
servershare.cpp:-0-:decodeQuery: REQUEST_METHOD = GET
servershare.cpp:-0-:decodeQuery: QUERY_STRING = req=rand&imsi=IMSI12345678901231
subscriberserver.cpp:-0-:logQuery: query
subscriberserver.cpp:-0-:logQuery: imsi -> IMSI12345678901231
subscriberserver.cpp:-0-:logQuery: req -> rand
servershare.cpp:-0-:generateRand: ki is unknown, rand is cached
subscriberserver.cpp:-0-:logResponse: response
subscriberserver.cpp:-0-:logResponse: rand=hexhexhexhexhexhexhexhexhexh1000
subscriberserver.cpp:-0-:logResponse: imsi=IMSI12345678901231
IMSI12345678901231|hexhexhexhexhexhexhexhexhexh1000|||
IMSI12345678901232||||
IMSI12345678901233|||hexhexhexhexhexhexhexhexhexh1000|
newname||||
Content-Type: text
rand=hexhexhexhexhexhexhexhexhexh1000
imsi=IMSI12345678901231
servershare.cpp:-0-:decodeQuery: REQUEST_METHOD = GET
servershare.cpp:-0-:decodeQuery: QUERY_STRING = req=rand&imsi=IMSI12345678901231
subscriberserver.cpp:-0-:logQuery: query
subscriberserver.cpp:-0-:logQuery: imsi -> IMSI12345678901231
subscriberserver.cpp:-0-:logQuery: req -> rand
servershare.cpp:-0-:generateRand: ki is unknown, rand is cached
subscriberserver.cpp:-0-:logResponse: response
subscriberserver.cpp:-0-:logResponse: rand=hexhexhexhexhexhexhexhexhexh1000
subscriberserver.cpp:-0-:logResponse: imsi=IMSI12345678901231
IMSI12345678901231|hexhexhexhexhexhexhexhexhexh1000|||
IMSI12345678901232||||
IMSI12345678901233|||hexhexhexhexhexhexhexhexhexh1000|
newname||||
Content-Type: text
rand=hexhexhexhexhexhexhexhexhexh1001
imsi=IMSI12345678901232
servershare.cpp:-0-:decodeQuery: REQUEST_METHOD = GET
servershare.cpp:-0-:decodeQuery: QUERY_STRING = req=rand&imsi=IMSI12345678901232
subscriberserver.cpp:-0-:logQuery: query
subscriberserver.cpp:-0-:logQuery: imsi -> IMSI12345678901232
subscriberserver.cpp:-0-:logQuery: req -> rand
servershare.cpp:-0-:generateRand: ki is unknown, rand is not cached
subscriberserver.cpp:-0-:logResponse: response
subscriberserver.cpp:-0-:logResponse: rand=hexhexhexhexhexhexhexhexhexh1001
subscriberserver.cpp:-0-:logResponse: imsi=IMSI12345678901232
IMSI12345678901231|hexhexhexhexhexhexhexhexhexh1000|||
IMSI12345678901232|hexhexhexhexhexhexhexhexhexh1001|||
IMSI12345678901233|||hexhexhexhexhexhexhexhexhexh1000|
newname||||
Content-Type: text
rand=hexhexhexhexhexhexhexhexhexh1001
imsi=IMSI12345678901232
servershare.cpp:-0-:decodeQuery: REQUEST_METHOD = GET
servershare.cpp:-0-:decodeQuery: QUERY_STRING = req=rand&imsi=IMSI12345678901232
subscriberserver.cpp:-0-:logQuery: query
subscriberserver.cpp:-0-:logQuery: imsi -> IMSI12345678901232
subscriberserver.cpp:-0-:logQuery: req -> rand
servershare.cpp:-0-:generateRand: ki is unknown, rand is cached
subscriberserver.cpp:-0-:logResponse: response
subscriberserver.cpp:-0-:logResponse: rand=hexhexhexhexhexhexhexhexhexh1001
subscriberserver.cpp:-0-:logResponse: imsi=IMSI12345678901232
IMSI12345678901231|hexhexhexhexhexhexhexhexhexh1000|||
IMSI12345678901232|hexhexhexhexhexhexhexhexhexh1001|||
IMSI12345678901233|||hexhexhexhexhexhexhexhexhexh1000|
newname||||
Content-Type: text
status=SUCCESS
servershare.cpp:-0-:decodeQuery: REQUEST_METHOD = GET
servershare.cpp:-0-:decodeQuery: QUERY_STRING = req=auth&imsi=IMSI12345678901233&rand=hexhexhexhexhexhexhexhexhexh1002&sres=hexh1003
subscriberserver.cpp:-0-:logQuery: query
subscriberserver.cpp:-0-:logQuery: imsi -> IMSI12345678901233
subscriberserver.cpp:-0-:logQuery: rand -> hexhexhexhexhexhexhexhexhexh1002
subscriberserver.cpp:-0-:logQuery: req -> auth
subscriberserver.cpp:-0-:logQuery: sres -> hexh1003
servershare.cpp:-0-:authenticate: ki known
servershare.cpp:-0-:authenticate: result = hexh1003
servershare.cpp:-0-:authenticate: returning = 1
subscriberserver.cpp:-0-:logResponse: response
subscriberserver.cpp:-0-:logResponse: status=SUCCESS
IMSI12345678901231|hexhexhexhexhexhexhexhexhexh1000|||
IMSI12345678901232|hexhexhexhexhexhexhexhexhexh1001|||
IMSI12345678901233|||hexhexhexhexhexhexhexhexhexh1000|
newname||||
Content-Type: text
status=FAILURE
servershare.cpp:-0-:decodeQuery: REQUEST_METHOD = GET
servershare.cpp:-0-:decodeQuery: QUERY_STRING = req=auth&imsi=IMSI12345678901233&rand=hexhexhexhexhexhexhexhexhexh1002&sres=hexh1004
subscriberserver.cpp:-0-:logQuery: query
subscriberserver.cpp:-0-:logQuery: imsi -> IMSI12345678901233
subscriberserver.cpp:-0-:logQuery: rand -> hexhexhexhexhexhexhexhexhexh1002
subscriberserver.cpp:-0-:logQuery: req -> auth
subscriberserver.cpp:-0-:logQuery: sres -> hexh1004
servershare.cpp:-0-:authenticate: ki known
servershare.cpp:-0-:authenticate: result = hexh1003
servershare.cpp:-0-:authenticate: returning = 0
subscriberserver.cpp:-0-:logResponse: response
subscriberserver.cpp:-0-:logResponse: status=FAILURE
IMSI12345678901231|hexhexhexhexhexhexhexhexhexh1000|||
IMSI12345678901232|hexhexhexhexhexhexhexhexhexh1001|||
IMSI12345678901233|||hexhexhexhexhexhexhexhexhexh1000|
newname||||

View File

@ -0,0 +1 @@
select name, rand, sres, ki, kc from sip_buddies;

89
test.subscriberserver/runtest Executable file
View File

@ -0,0 +1,89 @@
#!/bin/bash
rm -f /etc/OpenBTS/OpenBTS.db sr.db
sqlite3 /etc/OpenBTS/OpenBTS.db < subscriberserver.db.init
sqlite3 sr.db < sr.db.init
date > output.got
# test an sql update
logger -plocal7.Debug dwb syslog mark
REQUEST_METHOD=GET
export REQUEST_METHOD
QUERY_STRING="req=sql&stmts=insert into sip_buddies (name) values (\"newname\")"
export QUERY_STRING
../subscriberserver.cgi >> output.got
../syslogextractor >> output.got
sqlite3 sr.db < query.sql >> output.got
# test an sql query
logger -plocal7.Debug dwb syslog mark
REQUEST_METHOD=GET
export REQUEST_METHOD
QUERY_STRING="req=sql&stmts=select name from sip_buddies where id=2"
export QUERY_STRING
../subscriberserver.cgi >> output.got
../syslogextractor >> output.got
sqlite3 sr.db < query.sql >> output.got
# Some rand and auth tests just to see that things are connected ok.
# No need for exhaustive testing because the code is shared, and
# tested better elsewhere.
logger -plocal7.Debug dwb syslog mark
REQUEST_METHOD=GET
export REQUEST_METHOD
QUERY_STRING="req=rand&imsi=IMSI12345678901231"
export QUERY_STRING
../subscriberserver.cgi >> output.got
../syslogextractor >> output.got
sqlite3 sr.db < query.sql >> output.got
logger -plocal7.Debug dwb syslog mark
REQUEST_METHOD=GET
export REQUEST_METHOD
QUERY_STRING="req=rand&imsi=IMSI12345678901231"
export QUERY_STRING
../subscriberserver.cgi >> output.got
../syslogextractor >> output.got
sqlite3 sr.db < query.sql >> output.got
logger -plocal7.Debug dwb syslog mark
REQUEST_METHOD=GET
export REQUEST_METHOD
QUERY_STRING="req=rand&imsi=IMSI12345678901232"
export QUERY_STRING
../subscriberserver.cgi >> output.got
../syslogextractor >> output.got
sqlite3 sr.db < query.sql >> output.got
logger -plocal7.Debug dwb syslog mark
REQUEST_METHOD=GET
export REQUEST_METHOD
QUERY_STRING="req=rand&imsi=IMSI12345678901232"
export QUERY_STRING
../subscriberserver.cgi >> output.got
../syslogextractor >> output.got
sqlite3 sr.db < query.sql >> output.got
logger -plocal7.Debug dwb syslog mark
REQUEST_METHOD=GET
export REQUEST_METHOD
QUERY_STRING="req=auth&imsi=IMSI12345678901233&rand=d76fe9a5839089a2ebeb269b46bf46ff&sres=726259AF"
export QUERY_STRING
../subscriberserver.cgi >> output.got
../syslogextractor >> output.got
sqlite3 sr.db < query.sql >> output.got
logger -plocal7.Debug dwb syslog mark
REQUEST_METHOD=GET
export REQUEST_METHOD
QUERY_STRING="req=auth&imsi=IMSI12345678901233&rand=d76fe9a5839089a2ebeb269b46bf46ff&sres=726259A0"
export QUERY_STRING
../subscriberserver.cgi >> output.got
../syslogextractor >> output.got
sqlite3 sr.db < query.sql >> output.got
mv output.got ootput.got
../hexmapper ootput.got > output.got
diff output.exp output.got
exit 0

View File

@ -0,0 +1,101 @@
BEGIN TRANSACTION;
CREATE TABLE dialdata_table (
id INTEGER,
exten VARCHAR(40) NOT NULL DEFAULT '',
dial VARCHAR(128) NOT NULL DEFAULT '',
PRIMARY KEY (id)
);
INSERT INTO "dialdata_table" VALUES(1,'1000','1000');
INSERT INTO "dialdata_table" VALUES(2,'1001','1001');
INSERT INTO "dialdata_table" VALUES(3,'clid1','imsi1');
CREATE TABLE 'sip_buddies'
(
id integer,
name VARCHAR(80) unique not null,
context VARCHAR(80),
callingpres VARCHAR(30) DEFAULT 'allowed_not_screened',
deny VARCHAR(95),
permit VARCHAR(95),
secret VARCHAR(80),
md5secret VARCHAR(80),
remotesecret VARCHAR(250),
transport VARCHAR(10),
host VARCHAR(31) DEFAULT '' not null,
nat VARCHAR(5) DEFAULT 'no' not null,
type VARCHAR(10) DEFAULT 'friend' not null,
accountcode VARCHAR(20),
amaflags VARCHAR(13),
callgroup VARCHAR(10),
callerid VARCHAR(80),
defaultip VARCHAR(40) DEFAULT '0.0.0.0',
dtmfmode VARCHAR(7) DEFAULT 'rfc2833',
fromuser VARCHAR(80),
fromdomain VARCHAR(80),
insecure VARCHAR(4),
language CHAR(2),
mailbox VARCHAR(50),
pickupgroup VARCHAR(10),
qualify CHAR(3),
regexten VARCHAR(80),
rtptimeout CHAR(3),
rtpholdtimeout CHAR(3),
setvar VARCHAR(100),
disallow VARCHAR(100) DEFAULT 'all',
allow VARCHAR(100) DEFAULT 'ulaw' not null,
fullcontact VARCHAR(80),
ipaddr VARCHAR(40),
port int(5) DEFAULT 0,
username VARCHAR(80),
defaultuser VARCHAR(80),
subscribecontext VARCHAR(80),
directmedia VARCHAR(3),
trustrpid VARCHAR(3),
sendrpid VARCHAR(3),
progressinband VARCHAR(5),
promiscredir VARCHAR(3),
useclientcode VARCHAR(3),
callcounter VARCHAR(3),
busylevel int(11),
allowoverlap VARCHAR(3) DEFAULT 'yes',
allowsubscribe VARCHAR(3) DEFAULT 'yes',
allowtransfer VARCHAR(3) DEFAULT 'yes',
ignoresdpversion VARCHAR(3) DEFAULT 'no',
template VARCHAR(100),
videosupport VARCHAR(6) DEFAULT 'no',
maxcallbitrate int(11),
rfc2833compensate VARCHAR(3) DEFAULT 'yes',
'session-timers' VARCHAR(10) DEFAULT 'accept',
'session-expires' int(6) DEFAULT 1800,
'session-minse' int(6) DEFAULT 90,
'session-refresher' VARCHAR(3) DEFAULT 'uas',
t38pt_usertpsource VARCHAR(3),
outboundproxy VARCHAR(250),
callbackextension VARCHAR(250),
registertrying VARCHAR(3) DEFAULT 'yes',
timert1 int(6) DEFAULT 500,
timerb int(9),
qualifyfreq int(6) DEFAULT 120,
contactpermit VARCHAR(250),
contactdeny VARCHAR(250),
lastms int(11) DEFAULT 0 not null,
regserver VARCHAR(100),
regseconds int(11) DEFAULT 0 not null,
useragent VARCHAR(100),
cancallforward CHAR(3) DEFAULT 'yes' not null,
canreinvite CHAR(3) DEFAULT 'yes' not null,
mask VARCHAR(95),
musiconhold VARCHAR(100),
restrictcid CHAR(3),
calllimit int(5),
rand varchar(33) default '',
sres varchar(33) default '',
ki varchar(33) default '',
kc varchar(33) default '',
primary key(id)
);
insert into sip_buddies (name,rand,sres,ki,kc) values ('IMSI12345678901231','48091124c1155bd95c6f1860dc66ce92','','','');
insert into sip_buddies (name,rand,sres,ki,kc) values ('IMSI12345678901232','','','','');
insert into sip_buddies (name,rand,sres,ki,kc) values ('IMSI12345678901233','','','48091124c1155bd95c6f1860dc66ce92','');
COMMIT;

View File

@ -0,0 +1,7 @@
BEGIN TRANSACTION;
CREATE TABLE CONFIG ( KEYSTRING TEXT UNIQUE NOT NULL, VALUESTRING TEXT, STATIC INTEGER DEFAULT 0, OPTIONAL INTEGER DEFAULT 0, COMMENTS TEXT DEFAULT '');
INSERT INTO "CONFIG" VALUES('SubscriberRegistry.db','sr.db',0,0,'');
INSERT INTO "CONFIG" VALUES('SubscriberRegistry.A3A8','../comp128',0,0,'');
INSERT INTO "CONFIG" VALUES('SubscriberRegistry.UpstreamServer','',0,0,'');
INSERT INTO "CONFIG" VALUES('Log.Level','DEBUG',0,0,'');
COMMIT;