[Serusers] SIP Registration fail

William Zhang espzzh at gmail.com
Sun Apr 6 08:05:08 CEST 2008


Hi All,

I am new to SER. I might just made some simple mistakes.  So be easy
on me:)  I appreciate any inputs.

Basically  I was able to install and run SER 2.0.0 RC1 and make call
between SIP clients SJPhone 1.65 with a helloworld configuration. Now
I am trying to add the Authentication and MySQL. Here are what I did
so far and no luck to get it work:(
1. Generate the configuration files with configuration file
buildsystem and the content of the file is in the bottom of this
message.
2. Create the SER database in MySQL server by running the ser_mysql.sh
create command
3. Set SIP_DOMAIN variable: export SIP_DOMAIN="unknown.org"
4. Add domain and user with SER_CTL 2.0 with following commands
   ser_ctl domain add  unknown.org
   ser_ctl user   add  777 at unknown.org -p 1212

   The ser_ctl domain show and user show return:

   unknown.org unknown.org --------w--c-s
   777 at unknown.org uri 777 at unknown.org
   777 at unknown.org credentials username=777 realm=unknown.org password=1212
   777 at unknown.org attr datetime_created=2008-04-06 03:25:43

   I believe this should set the user and domain correctly to the database.
   But I also got some weired output with other command like ser_ctl
ps, ser_ctl version. Same error:
   ser_ctl: (97, 'Address family not supported by protocol'): error'>

   And sercmd also give me the follow errors:(
   ERROR: connect_unix_sock: connect(/tmp/ser_ctl): Connection refused [111]
5. Run the ser with error to console and no fork.
6. Configure the SJPhone with above registration information.

The client can not register and got 401 Unauthorized response. Below
are the SIP packets contents:

2008-04-06 04:49:29.843 UDP LOCAL->192.168.0.182:5060

REGISTER sip:unknown.org SIP/2.0

Via: SIP/2.0/UDP
192.168.0.179;branch=z9hG4bKc0a800b30000004947f8565900000d5f00000019;rport

From: "unknown" <sip:777 at unknown.org>;tag=4ff22665b92

To: <sip:777 at unknown.org>

Contact: <sip:777 at 192.168.0.179>

Call-ID: C69D49CA6580482CAFB5D305213ACE0D0xc0a800b3

CSeq: 18 REGISTER

Max-Forwards: 70

User-Agent: SJphone/1.65.377a (SJ Labs)

Content-Length: 0





21:49:29 SIP.Network DEBUG

2008-04-06 04:49:29.843 UDP 192.168.0.182:5060->LOCAL

SIP/2.0 401 Unauthorized

Via: SIP/2.0/UDP
192.168.0.179;branch=z9hG4bKc0a800b30000004947f8565900000d5f00000019;rport=5060

From: "unknown" <sip:777 at unknown.org>;tag=4ff22665b92

To: <sip:777 at unknown.org>;tag=3594b9925f930dcc8b38a6cda152d6b5.f97a

Call-ID: C69D49CA6580482CAFB5D305213ACE0D0xc0a800b3

CSeq: 18 REGISTER

Server: Sip EXpress router (2.0.0-rc1 (i386/linux))

Content-Length: 0

Warning: 392 192.168.0.182:5060 "Noisy feedback tells:  pid=14897
req_src_ip=192.168.0.179 req_src_port=5060 in_uri=sip:unknown.org
out_uri=sip:unknown.org via_cnt==1"



The contents of the ser.cfg file:

# Debug level on logging
debug=3
# memory debug log level
memdbg=10
# memory statistics log level
memlog=10
# Fork and create children (no=run single process for debugging purposes)
fork=no
# Log to stderr (only use this of fork=no)
log_stderror=yes
# Log to the defined syslog facility
log_facility=LOG_LOCAL0
# IP address to listen to
listen=192.168.0.182
# Port to listen on
port=5060
# Aliases used by uri!=myself checks to identity locally destined messages
alias=mytestser.org
# Number of children to fork per port per protocol
children=4
# Is this host multihomed?
mhomed=no
# Should dns resolving be used?
dns=no
# Should reverse dns resolving be used?
rev_dns=no
# Should reverse dns resolving be used?
disable_core_dump=yes
# *************Your local directives *****************
# *** Common
# *** Specific

# Load the stateless transaction module (sl_reply etc)
loadmodule "/usr/local/lib/ser/modules/sl.so"
# Load the transaction stateful module (t_relay() etc)
loadmodule "/usr/local/lib/ser/modules/tm.so"
# Load the record routing module. Needed for making sure messages go
through our server
loadmodule "/usr/local/lib/ser/modules/rr.so"
# Load maxfwd for stopping loops
loadmodule "/usr/local/lib/ser/modules/maxfwd.so"
# Load the user location module to store and retrieve user locations
loadmodule "/usr/local/lib/ser/modules/usrloc.so"
# Load the registrar module to handle registrations
loadmodule "/usr/local/lib/ser/modules/registrar.so"
# Load the xlog module for advanced logging with parameters
loadmodule "/usr/local/lib/ser/modules/xlog.so"
# Load the ctl module for the control socket interface.
loadmodule "/usr/local/lib/ser/modules/ctl.so"
# Load the gflags, global flags module.
loadmodule "/usr/local/lib/ser/modules/gflags.so"
# Load textops used for searching/selecting text in messages and
manipulating headers.
loadmodule "/usr/local/lib/ser/modules/textops.so"
# Load the sanity check module to do integrity checks on incoming messages.
loadmodule "/usr/local/lib/ser/modules/sanity.so"
# Load the mysql connector module.
loadmodule "/usr/local/lib/ser/modules/mysql.so"

# Load the auth module with all the core authentication functions.
loadmodule "/usr/local/lib/ser/modules/auth.so"

# Load the auth module with the database functions.
loadmodule "/usr/local/lib/ser/modules/auth_db.so"
# The uri_db module uses database to check the uri.
loadmodule "/usr/local/lib/ser/modules/uri_db.so"
# The avp_db module allows loading of user attributes from database.
loadmodule "/usr/local/lib/ser/modules/avp_db.so"
loadmodule "/usr/local/lib/ser/modules/avp.so"
# Load domain module used to verify the local domains.
loadmodule "/usr/local/lib/ser/modules/domain.so"
# *** Your loaded modules

# Flags set be various modules

# We set database mode to 0 = do not save to database backend (keep in
memory), 1 = write-through to database
modparam("usrloc", "db_mode", 1)
# ctl module params
# by default ctl listens on unixs:/tmp/ser_ctl if no other address is
# specified in modparams; this is also the default for sercmd
modparam("ctl", "binrpc", "unixs:/tmp/ser_ctl")
# listen on the "standard" fifo for backward compatibility
modparam("ctl", "fifo", "fifo:/tmp/ser_fifo")
# We turn on full lr (adds lr=on as uri parameter, not lr).
# This should have higher compatibility with some user agents.
modparam("rr", "enable_full_lr", 1)
# Encrypt dialog cookies with this secret
modparam("rr", "cookie_secret", "ChangeThisIfYouStoreSecretStuffInCookie")
# The authentication related modules and which database to use.
modparam("auth_db|usrloc|uri_db", "db_url", "mysql://ser:heslo@localhost/ser")

# We can store some of our important attributes (inside the messages)
avpflags
  dialog_cookie;


# ************* Your local module parameters *****************
# *** Common
# *** Specific

# Main route, executed for all messages
route {
	# ------------------------------------------------------------------------
	# Sanity Check Section
	# ------------------------------------------------------------------------
	sanity_check();
	# Check whether we might be in a loop.
	if (!mf_process_maxfwd_header("10")) {
		sl_reply("483", "Too Many Hops");
		exit;
	}
	if (msg:len > max_len) {
		sl_reply("513", "Message Overflow");
		exit;
	}

# Log all incoming messages to see start of processing
if(is_gflag("29")){
  xlog("L_NOTICE","INCOMING - %rm\nFrom: %is(%fu)\nTo: %ru\nCall-ID: %ci\n");
}


	# ------------------------------------------------------------------------
	# Handling messages with Route headers (aka loose routing)
	# ------------------------------------------------------------------------

	if (loose_route()) {
		if(is_gflag("31")){
  xlog("L_NOTICE","    loose routed - %rm\nFrom: %is(%fu)\nTo:
%ru\nCall-ID: %ci\n");
}
		route(RELAY);
		exit;
	}

	# ------------------------------------------------------------------------
	# Record Route Section
	# ------------------------------------------------------------------------
	else if (method!="REGISTER") {
		record_route();
	};

	# If the ACK has more hops before reaching the user agent, it will
have a Route header
	# and be forwarded above. If next hop is a user agent, the Request
URI will be the ip:port
	# found in Contact of the original OK from the user agent, but will
not be loose routed.
	# Just relay the ACK to the user agent.
	if (method=="ACK") {

if(is_gflag("31")){
  xlog("L_NOTICE","    ACK relayed using ruri - %rm\nFrom:
%is(%fu)\nTo: %ru\nCall-ID: %ci\n");
}

		route(RELAY);
		exit;
	}




	# check if the caller is from a local domain (f=from, d=domain, $f will be set)
	lookup_domain("$fd", "@from.uri.host");

	# check if the callee is at a local domain (t=to, d=domain, $t will be set)
	# If we have no To tag (dialog creating messages), we use request uri, but
	# but if this is an in-dialog message (like BYE with last hop before UA here)
	# we use the To header.
	if(@to.tag=="") {
		lookup_domain("$td", "@ruri.host");
	} else {
		lookup_domain("$td", "@to.uri.host");
	}

	# we dont know the domain of the caller and also not
	# the domain of the callee -> someone uses our proxy as
	# a relay

	if (!$t.did && !$f.did) {
		sl_reply("403", "Relaying Forbidden");
		exit;
	}
	



	# ------------------------------------------------------------------------
	# Message Type Processing Section
	# NOTE!!! It is assumed that all messages reaching this point are destined
	# for the local server (REGISTER) or for UAs registered locally. (see
nonlocal.m4)
	# ------------------------------------------------------------------------
	if (method=="REGISTER") {
		route(REGISTER);
		exit;
	}


	# Authenticate
	route(AUTHENTICATE);



	# All local, non-ACKs, non-REGISTER are assumed to be part of a potential
	# new dialog (standalone MESSAGE and NOTIFYs without dialog-creation
will ex. also reach here)
	route(NEWDIALOG);

	# By now, the request uri should be correct, relay
if(is_gflag("29")){
  xlog("L_NOTICE","No route matched for the request\nCall-Id: %ci\n");
};
	sl_reply("404", "No route matched");


}
# end main route

route[RELAY] {

# Log all outgoing messages
if(is_gflag("29")){
  xlog("L_NOTICE","OUTGOING - %rm\nFrom: %is(%fu)\nTo: %ru\nCall-ID: %ci\n");
}	# ------------------------------------------------------------------------
	# Default Message Handler
	# ------------------------------------------------------------------------
	# t_relay will act based on the current request URI, as well as any
	# overruling received parameters (i.e. for NATed user agents)
	# UDP to TCP and vice versa works as well.

	if (!t_relay()) {
	      	sl_reply_error();
	};
	exit;
}

route[REGISTER] {
	# ------------------------------------------------------------------------
	# REGISTER Message Handler
	# ------------------------------------------------------------------------


	# From lookup_domain, $t.did should be set if we found the domain as ours.
	if (!$t.did) {
		if(is_gflag("29")){
  xlog("L_NOTICE","%rm  From <%fu>  Attempted REGISTER from non-local
domain\nCall-ID: %ci\n");
};
		sl_reply("403", "Attempting to register with unknown domain");
		exit;
	}
	
	# We check that Authorization header in the message contains valid
credentials found in the
	# table with the same name.
	if (!www_authenticate("$fd.digest_realm", "credentials")) {
	
		# $? represents the return error code from www_authenticate()
		if ($? == -2) {
			if(is_gflag("31")){
  xlog("L_NOTICE","    REGISTER - %rm  From <%fu>  500 Internal Server
Error\nCall-ID: %ci\n");
};
			sl_reply("500", "Internal Server Error");
		} else if ($? == -3) {
			if(is_gflag("31")){
  xlog("L_NOTICE","    REGISTER - %rm  From <%fu>  400 Bad Request\n");
};
			sl_reply("400", "Bad Request");
		} else {

			# After www_authenticate(), $digest_challenge should be set if no
credentials were found.
			# We append the challenge to reply and send 401 Unauthorized.
			if ($digest_challenge) {
				append_to_reply("%$digest_challenge");
			}
			sl_reply("401", "Unauthorized");
		}
	
		# We didn't have a valid set of credentials, so we exit.
		exit;
	}

	# www_authenticate set $uid, so let's store it.
	$authuid=$uid;


	# Check if the authenticated user is the same as the target user.
	# We use the uri in the To field to lookup the user's uid. If none is
found, the To user is unknown.
	if (!lookup_user("$tu.uid", "@to.uri")) {
		sl_reply("404", "Trying to register unknon user (To)");
		exit;
	}

	# $f.uid set by www_authenticate() should match the uid we should looked up
	if ($authuid != $tu.uid) {
		sl_reply("403", "Authentication and To-Header mismatch");
		exit;
	}
	

	# We use the uri in From to look up the uid.
	if (!lookup_user("$fu.uid", "@from.uri")) {
		sl_reply("404", "Expect a known user in From");
		exit;
	}

	# The looked up $fu.uid is checked against the Authentication user
	if ($authuid != $fu.uid) {
		sl_reply("403", "Authentication and From-Header mismatch");
		exit;
	}

	if (!save_contacts("location")) {
		sl_reply("400", "Invalid REGISTER Request");
		exit;
	};

	exit;
} # End route[REGISTER]


route[AUTHENTICATE]
{
	# RFC3261 says you are not allowed to challenge these methods
	if (method=="CANCEL" || method=="ACK") {
		return;
	}

	# We check that Authorization header in the message contains valid
credentials found in the
	# table with the same name.
	if (!proxy_authenticate("$fd.digest_realm", "credentials")) {
	
		# $? represents the return error code from proxy_authenticate()
		if ($? == -2) {
			if(is_gflag("31")){
  xlog("L_NOTICE","    AUTHENTICATE - %rm  From <%fu>  500 Internal
Server Error\nCall-ID: %ci\n");
};
			sl_reply("500", "Internal Server Error");
		} else if ($? == -3) {
			if(is_gflag("31")){
  xlog("L_NOTICE","    AUTHENTICATE - %rm  From <%fu>  400 Bad Request\n");
};
			sl_reply("400", "Bad Request");
		} else {

			# After www_authenticate(), $digest_challenge should be set if no
credentials were found.
			# We append the challenge to reply and send 407 Proxy
Authentication Required.
			if ($digest_challenge) {
				append_to_reply("%$digest_challenge");
			}
			sl_reply("407", "Proxy Authentication Required");
		}
	
		# We didn't have a valid set of credentials, so we exit.
		exit;
	}

	# proxy_authenticate set $uid, so let's store it.
	$authuid=$uid;


	# Use the uri in the From header and look up the uid. If not found,
delete the uri attribute.
	if (!lookup_user("$fu.uid", "@from.uri")) {
		del_attr("$uid");
	}

	# Check the found uid against the authenticated uid.
	if ($fu.uid != $authuid) {
		sl_reply("403", "Fake Identity");
		exit;
	}

	# load the user attributes (preferences) of the caller. $fu.yourattr
should now be set if set in the
	# user preferences table.
	load_attrs("$fu", "$f.uid");

}

route[NEWDIALOG] {

	# If we don't know the user, it is not for a local user.
	if (!lookup_user("$tu.uid", "@ruri")) {
		# User is not known and request uri does not match PSTN dialplan.
		return;


	}

	if (!lookup_contacts("location")) {
		if(is_gflag("30")){
  xlog("L_NOTICE","    NEWDIALOG - 480 User Offline\nCall-Id: %ci\n");
};
		sl_reply("480", "User Offline");
		exit;
	}
	# Relay it to the location(s) of the found user
	route(RELAY);
	exit;


} # End route[NEWDIALOG]



More information about the sr-users mailing list