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@unknown.org -p 1212
The ser_ctl domain show and user show return:
unknown.org unknown.org --------w--c-s 777@unknown.org uri 777@unknown.org 777@unknown.org credentials username=777 realm=unknown.org password=1212 777@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@unknown.org;tag=4ff22665b92
Contact: sip:777@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@unknown.org;tag=4ff22665b92
To: sip:777@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]