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:
parent
dd1d7d3109
commit
baf5fdf717
12
COPYING
12
COPYING
|
@ -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
|
||||
|
|
41
Makefile
41
Makefile
|
@ -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)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
4
config.h
4
config.h
|
@ -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). */
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
# A script to restart and just keep sipauthserve running.
|
||||
while true; do killall sipauthserve; sleep 2; ./sipauthserve; done
|
208
servershare.cpp
208
servershare.cpp
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
|
@ -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");
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
@ -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();
|
||||
}
|
|
@ -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)
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||
|
||||
|
||||
}
|
|
@ -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;
|
|
@ -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;
|
|
@ -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
|
|
@ -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||
|
|
@ -0,0 +1 @@
|
|||
select name, rand, sres, ki, kc from sip_buddies;
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
|
@ -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;
|
|
@ -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.
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,2 @@
|
|||
select name, username, type, context, host from sip_buddies;
|
||||
select exten, dial from dialdata_table;
|
|
@ -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
|
|
@ -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;
|
||||
|
|
@ -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;
|
|
@ -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||||
|
|
@ -0,0 +1 @@
|
|||
select name, rand, sres, ki, kc from sip_buddies;
|
|
@ -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
|
|
@ -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;
|
|
@ -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;
|
Loading…
Reference in New Issue