[OpenSER-Devel] uac module authentication

Marc LEURENT lftsy at free.fr
Tue Jul 31 18:27:56 CEST 2007


Since anybody have been able to fully answer my question on OpenSER-Users, I would be very grateful if you can help my to understand how is it
possible to use the module...
I would like to handle SIP/PSTN gateway directly with OpenSER, without Asterisk. But my gateway need to be registered, so the forward of INVITE
request cannot work without previous registration..
I already have radius AAA working, NAT traversal using STUN and CDRTool to generate tickets


I used the http://www.voice-system.ro/docs/uac/ar01s06.html#ex_auth tutorial and my problem is that INVITE request are forward without a previous
REGISTER one, so I get a 403 forbidden answer...


Thank you for your answers...

Best Regards



Here is my openser.cfg file:


#
# $Id: openser.cfg 1827 2007-03-12 15:22:53Z bogdan_iancu $
#
# simple quick-start config script
# Please refer to the Core CookBook at http://www.openser.org/dokuwiki/doku.php
# for a explanation of possible statements, functions and parameters.
#

# ----------- global configuration parameters ------------------------

debug=7            # debug level (cmd line: -dddddddddd)
fork=no
log_stderror=yes    # (cmd line: -E)
children=4

listen=192.168.95.248
alias=sip.wifirst.fr

port=5060

# uncomment the following lines for TLS support
#disable_tls = 0
#listen = tls:192.168.95.248:5061
#alias=sip.wifirst.fr
#tls_verify_server = 1
#tls_verify_client = 1
#tls_require_client_certificate = 0
#tls_method = TLSv1
#tls_certificate = "/etc/openser/tls/user/user-cert.pem"
#tls_private_key = "/etc/openser/tls/user/user-privkey.pem"
#tls_ca_list = "/etc/openser/tls/user/user-calist.pem"

#server_signature=yes
#tos=IPTOS_LOWDELAY


avp_aliases="day=i:101;time=i:102;can_uri=i:800;s_ip=i:801;billing_party=i:802;from_header=i:803;sip_proxy_ip=i:804"
#;pstnuser=i:805;pstnpassword=i:806:pstnrealm=i:807"


# ------------------ module loading ----------------------------------

#set module path
mpath="/usr/lib/openser/modules/"

# Uncomment this if you want to use SQL database
loadmodule "mysql.so"

loadmodule "sl.so"                      # Stateless Module
loadmodule "tm.so"                      # Transaction Module
loadmodule "rr.so"                      # Record-Route and Route Module
loadmodule "maxfwd.so"                  # Max-Forward processor Module
loadmodule "usrloc.so"                  # User Location Implementation Module
loadmodule "registrar.so"               # SIP Registrat Implementation Module
loadmodule "textops.so"                 # Text Operation Module
loadmodule "mi_fifo.so"                 # FIFO transport layer implementation for Management Interface

loadmodule "acc.so"                     # Accounting Module
loadmodule "avpops.so"                  # AVP Operation Module (user preference)
loadmodule "uri.so"                     # Generic URI operation Module

loadmodule "auth.so"                    # Authentification Module
#loadmodule "auth_db.so"                        # Database-backend Authentication mMdule
loadmodule "auth_radius.so"             # RADIUS-backend Authentication Module
loadmodule "group_radius.so"            # User-groups Module with RADIUS-backend
#loadmodule "avp_radius.so"             # RADIUS-backend for AVP loading Module

#loadmodule "presence.so"               # Presence server Module
#loadmodule "pua.so"                    # Common API for presence user agent client

loadmodule "options.so"                 # OPTIONS server replier Module
loadmodule "xlog.so"                    # Advanced Logger Module

#loadmodule "nathelper.so"              # NAT Traversal Helper Module
#loadmodule "dispatcher.so"             # Dispatcher (load-balancer) Module

loadmodule "uac.so"                     # User Agent Client
loadmodule "siptrace.so"                # SipTrace module (storage of SIP requests)
#loadmodule "exec.so"                   # Allows to start an external command from a OpenSER script

# ----------------- setting module-specific parameters ---------------


# -- exec params --
#modparam("exec", "setvars", 1)         # Turn off to disable setting environment variables for executed commands
#modparam("exec", "time_to_kill", 20)   # longest time a program is allowed to execute


# -- maxfwd params --
modparam("maxfwd", "max_limit", 10)     # Default is 256 | 10 in the functions


# -- sl params --
#modparam("sl", "enable_stats", 1)


# -- mi_fifo params --
modparam("mi_fifo", "fifo_name", "/tmp/openser_fifo")


# -- usrloc params --
# Uncomment this if you want to use SQL database
modparam("usrloc", "db_mode", 1)                        # Write instantaneously in the DB
modparam("usrloc", "db_url", "mysql://openser:razovski@sip.wifirst.fr/openser")
modparam("usrloc", "timer_interval", 10)
#modparam("usrloc", "use_domain", 1)                    # Not working for now...
modparam("usrloc", "cseq_delay", 5)                     # Delay before authorizing others retransmissions
#modparam("usrloc", "matching_mode", 1)                 # 1 - CONTACT and CALLID based matching algorithm
#modparam("usrloc", "nat_bflag" , 3)


# -- rr params --
modparam("rr", "enable_full_lr", 1)             # add value to ;lr param to make some broken UAs happy
#modparam("rr", "add_username", 1)              # username is added to the record-route


# -- siptrace params --
modparam("siptrace", "db_url", "mysql://openser:razovski@sip.wifirst.fr/openser")
modparam("siptrace", "table", "sip_trace")              # Default value "sip_trace"
modparam("siptrace", "trace_on", 1)


# -- avpops params --
#modparam("avpops", "avp_aliases", "day=i:101;time=i:102")      # Deprecated


# -- presence params --
#modparam("presence", "db_url", "mysql://openser:razovski@192.168.95.248/openser")
#modparam("presence", "max_expires", 3600)
#modparam("presence", "force_active", 1)
#modparam("presence", "server_address", "sip:sip.wifirst.fr:5060" )


# -- pua params --
#modparam("pua", "db_url", "mysql://openser:razovski@192.168.95.248/openser")


# -- options params --
#modparam("options", "accept", "*/*")
#modparam("options", "accept", "*/sdp")
#modparam("options", "accept_encoding", "") # gzip non supporte
#modparam("options", "accept_language", "en")


# -- registrar params --
modparam("registrar", "default_expires", 1800)
#modparam("registrar", "nat_flag", 6)
#modparam("registrar", "min_expires", 60)
#modparam("registrar", "max_expires", 0)
#modparam("registrar", "retry_after", 30)
#modparam("registrar", "received_avp", "$avp(i:42)")


# -- nathelper params --
#modparam("nathelper", "rtpproxy_sock", "udp:127.0.0.1:22222")
#modparam("nathelper", "natping_interval", 10)
#modparam("nathelper", "ping_nated_only", 1)
#modparam("nathelper", "sipping_bflag", 7)
##modparam("nathelper", "sipping_method", "OPTIONS")
#modparam("nathelper", "received_avp", "$avp(i:42)")            # Same Value as the registrar module
#modparam("nathelper", "sipping_from", "sip:pinger at sip.wifirst.fr")


# -- dispatcher params --
#modparam("dispatcher", "list_file", "/etc/openser/dispatcher.list")
#modparam("dispatcher", "force_dst", 1)  # Force overwriting of the destination
#modparam("dispatcher", "flags", 3)

#modparam("dispatcher", "use_default", 1)
#modparam("dispatcher", "dst_avp", "$avp(i:271)")
#modparam("dispatcher", "grp_avp", "$avp(i:272)")
#modparam("dispatcher", "cnt_avp", "$avp(i:273)")



# -- uac params --
#modparam("uac", "credential", "1401:saturne.alsion.com:7hR")
modparam("uac", "credential", "0824:sip.plugandtel.net:635xyM")
#modparam("uac", "auth_username_avp", "$avp(i:901)")    #
#modparam("uac", "auth_password_avp", "$avp(i:902)")    #
#modparam("uac", "auth_realm_avp", "$avp(i:903)")       #
modparam("uac","from_restore_mode","auto")              # sequential requests and replies will be automatically updated based on stored original URI
modparam("uac","from_passwd","UGKZ7DIGIVyfgugdygièè§!yF7TR67")  # String password to be used to encrypt the RR storing paramter.





# -- auth_db params --
# Uncomment if you are using auth module
#modparam("auth_db", "db_url", "mysql://openser:razovski@192.168.95.248/openser")
#modparam("auth_db", "calculate_ha1", yes)
#modparam("auth_db", "password_column", "password")


# -- auth params --
#modparam("auth", "secret", "johndoessecretphrase")                     # Default is random => don't set it
#modparam("auth", "nonce_expire", 300)                                  # Time before nounce expiration
modparam("auth_radius", "radius_config", "/etc/radiusclient-ng/radiusclient.conf")


# -- group_radius params --
modparam("group_radius", "radius_config", "/etc/radiusclient-ng/radiusclient.conf")
modparam("group_radius", "use_domain", 1)       # username at domain will be used for lookup


# -- avp_radius parameter --
#modparam("avp_radius", "radius_config", "/etc/radiusclient-ng/radiusclient.conf")


# -- acc params (with radius )--
modparam("acc", "radius_config", "/etc/radiusclient-ng/radiusclient.conf")
modparam("acc", "radius_flag", 1)
modparam("acc", "radius_missed_flag", 2)

modparam("acc", "early_media", 1)
modparam("acc", "report_cancels", 1)
#modparam("acc", "report_ack", 0)
modparam("acc", "detect_direction", 1)
#modparam("acc", "log_flag", 1)         # number of the flag which will be used to mark messages for accounting
#modparam("acc", "log_level", 1)        # Set the reporting log level
#modparam("acc", "log_missed_flag", 2)  #
#modparam("acc", "failed_transaction_flag", 2)
modparam("acc", "service_type", 15)     # Radius service type used for accounting : 15 = (SIP)
#modparam("acc", "radius_extra", "Sip-Src-IP=$si;Sip-Src-Port=$sp")
# ATTENTION: DO NOT PUT ; at the end of the radius_extra attribute
modparam("acc", "radius_extra",         "Sip-Src-IP=$si;
                                        Sip-Src-Port=$sp;
                                        Canonical-URI=$avp(can_uri);
                                        Billing-Party=$avp(billing_party);
                                        SIP-Proxy-IP=$avp(sip_proxy_ip);
                                        User-Agent=$ua
                                        ")
                                        #Billing-Party=$avp(billing_party)
                                        #From-Header=$hdr(from);
                                        #User-Name=$fU;
                                        #From-Header=$avp(from_header);
                                        #Digest-Realm=$fd
                                        #Sip-From-Tag=$avp(from_header);
                                        #SIP-Method=$rm;

######## Pseudo Variables #######
#  http://openser.org/dokuwiki/doku.php/pseudovariables:1.2.x

#modparam("acc", "radius_extra",       "Sip-RPid=$avp(s:rpid); \
#                                       Source-IP=$si; \
#                                       Source-Port=$sp; \
#                                       Canonical-URI=$avp(can_uri); \
#                                       Billing-Party=$avp(billing_party); \
#                                       Divert-Reason=$avp(s:divert_reason); \
#                                       X-RTP-Stat=$avp(s:rtp_statistics); \
#                                       From-Header=$hdr(from); \
#                                       User-Agent=$hdr(user-agent); \
#                                       Contact=$hdr(contact); \
#                                       Event=$hdr(event); \
#                                       SIP-Proxy-IP=$avp(s:sip_proxy_ip)")


# -- acc params (with mysql) --
#modparam("acc", "db_url", "mysql://openser:razovski@sip.wifirst.fr/openser")
#modparam("acc", "db_flag", 1)
#modparam("acc", "db_missed_flag", 2)
#modparam("acc", "log_flag", 1)
#modparam("acc", "log_missed_flag", 2)


# -- xlog param --
#modparam("xlog", "force_color", 1)


# -------------------------  request routing logic -------------------

# main routing logic

route{

        # initial sanity checks -- messages with
        # max_forwards==0, or excessively long requests
        if (!mf_process_maxfwd_header("10")) {
                sl_send_reply("483","Too Many Hops");
                exit;
        };

        if (msg:len >=  2048 ) {
                sl_send_reply("513", "Message too big");
                exit;
        };


        # check if user is suspended
#       if(is_method("REGISTER|INVITE|MESSAGE|OPTIONS|SUBSCRIBE")){
#               if (radius_is_user_in("From", "suspended")) {
#                       sl_send_reply("403", "Forbidden - suspended");
#                       exit;
#               };
#       };

#       if(is_method("INVITE")) {
#               if (!radius_is_user_in("From","voip")) {
#                       xlog("L_DBG","NOT IN THE voip GROUP \r\n");
#                       sl_send_reply("403", "Forbidden - Not in the voip group");
#               } else {
#                       xlog("L_DBG","IN THE voip GROUP\r\n");
#               };
#       };


        # we record-route all messages -- to make sure that
        # subsequent messages will go through our proxy; that's
        # particularly good if upstream and downstream entities
        # use different transport protocol
        if (!method=="REGISTER") {
                record_route();
        };

        # subsequent messages withing a dialog should take the
        # path determined by record-routing
        if (loose_route()) { # mark routing logic in request
                append_hf("P-hint: rr-enforced\r\n");
                if(is_method("BYE")) { # log it all the time
                        acc_rad_request("200 ok");
                        acc_log_request("200 ok");
                }
                route(1);
        };

        #if (!uri==myself) {
                # mark routing logic in request
                # append_hf("P-hint: outbound\r\n");
                # if you have some interdomain connections via TLS
                #if(uri=~"@tls_domain1.net") {
                #       t_relay("tls:domain1.net");
                #       exit;
                #} else if(uri=~"@tls_domain2.net") {
                #       t_relay("tls:domain2.net");
                #       exit;
                #}
                #route(1);
        #};



################ SECTION USED TO ANSWER ping OPTIONS requests #################

        if (uri==myself) {
                if (method==OPTIONS){
                        if (uri=~"sip:ping[@]+.*") {
                                rewriteuri("sip:sip.wifirst.fr");
                                #rewriteuri("sip:$dd");
                                xlog("URI AFTER rewriteuri() = $ru \r\n");
                                options_reply();
                                exit;
                        };
                        if (! uri=~"sip:.*[@]+.*") {
                                xlog("URI USED FOR PING = $ru \r\n");
                                options_reply();
                        };
                };
        };


################################################################################


#################### REDIRECT PSTN PHONE CALLS##################################


        # set failure route for authentication
        t_on_failure("3");
        # reset flag to mark no authentication yet performed
        resetflag(7);

        if (method==INVITE && uri=~"sip:0677832974@*") {
#               #append_time();                                                 # Should add time
#               insert_hf("Mon-Premier-Test: marc at leurent.eu\r\n", "Call-ID");  # Add a new field to SDP
#               #rewritehost("10.10.10.1");                                     # Rewrite network address
#               consume_credentials();
#               $avp(i:901) = "084";
#               $avp(i:902) = "63yM";
#               $avp(i:903) = "sip.plugandtel.net";

#               rewritehostport("saturne.alsion.com");
                rewritehostport("sip.plugandtel.net");

                #uac_replace_from("sip:104 at sip.wifirst.fr");


                # forward to PSTN
                #t_relay("udp:saturne.alsion.com:5060");
                t_relay("udp:sip.plugandtel.net:5060");

                exit;

        };
################################################################################

        # Set the acc flags
        if(is_method("INVITE") && !has_totag()) {
                xlog("L_INFO", "I AM SETTING THE FLAGS FOR RADIUS \r\n");
                $avp(can_uri) = $ru;            # SIP Request's URI
                $avp(billing_party) = $fu;      # From URI
                $avp(from_header) = $fU;        # From URI username
                $avp(sip_proxy_ip) = $Ri;       # Received IP address

                setflag(1);             # radius_flag
                setflag(2);             # radius_missed_flag
        };


        # Functions when calling other domains
        if (!uri==myself) {
                # check if user is allowed to do voip calls to other domains
                if(is_method("INVITE|MESSAGE")) {
                        if (radius_is_user_in("From", "voip")) {
                                sl_send_reply("403", "Forbidden VoIP");
                                exit;
                        };
                };
                # mark routing logic in request
                append_hf("P-hint: outbound\r\n");
                route(1);
        };






        # if the request is for other domain use UsrLoc
        # (in case, it does not work, use the following command
        # with proper names and addresses in it)
        if (uri==myself) {

                if (method=="REGISTER") {
                        sip_trace();
                        xlog("L_INFO", "$si IS TRYING TO REGISTER \r\n");

                        # Uncomment this if you want to use digest authentication
#                       if (!www_authorize("sip.wifirst.fr", "subscriber")) {
#                               www_challenge("sip.wifirst.fr", "1");           # qop set to 1
#                               xlog("L_INFO", "WWW_CHALLENGE of $si FAILED \r\n");
#                               exit;
#                       };

                        if (!radius_www_authorize("sip.wifirst.fr")) {
                                www_challenge("sip.wifirst.fr", "0");           # qop set to 1
                                xlog("L_INFO", "WWW_CHALLENGE of $si FAILED \r\n");
                                exit;
                        };

                        # check the src ip address
                        #if(!avp_check("$avp(i:2)", "eq/$src_ip/ig")) {
                        #       sl_send_reply("403", "Forbidden IP");
                        #       exit;
                        #};

                        save("location");
                        xlog("L_INFO", "SAVE LOCATION OF $si \r\n");
                        exit;
                };


#               # calls to pstn
#               if(uri=~"sip:[0-9]*+@") {
#                       if(is_method("INVITE") && !has_totag()) {
#                               if (!radius_is_user_in("From", "pstn")) {
#                                       sl_send_reply("403", "Forbidden PSTN");
#                                       exit;
#                               };
#                       };
#                       # set gateway address
#                       rewritehostport("sip.wifirst.fr:5090");
#                       route(1);
#               };


                # load callee's avps
#               if(avp_load_radius("callee")) {
#                       # check if user has time filter enabled
#                       if(avp_check("$avp(i:3)", "eq/i:1")) {
#                               # print time in an avp
#                               avp_printf("$avp(i:100)", "$Tf");
#                               # extract day
#                               avp_subst("$avp(i:100)/$avp(i:101)", "/(.{3}) .+/*\1*/");
#                               #if(!avp_check("$avp(i:6)", "fm/$avp($day)")) {
#                               if(!avp_check("$avp(i:6)", "fm/$avp(day)")) {
#                                       sl_send_reply("403", "Forbidden - day");
#                                       exit;
#                               };
#                               # extract 'hours:minutes'
#                               avp_subst("$avp(i:100)/$avp(i:102)", "/(.{10}) (.{5}):.+/\2/");
#                               if((is_avp_set("$avp(i:4)") && avp_check("$avp(i:4)", "gt/$avp(time)"))
#                               || (is_avp_set("$avp(i:5)") && avp_check("$avp(i:5)", "lt/$avp(time)"))) {
#                                       sl_send_reply("403", "Forbidden - time");
#                                       exit;
#                               };
#                       };



#               lookup("aliases");
#               if (!uri==myself) {
#                       append_hf("P-hint: outbound alias\r\n");
#                       route(1);
#               };

                # native SIP destinations are handled using our USRLOC DB


                if (!lookup("location")) {
                        # log to acc as missed call
                        acc_rad_request("404 Not Found");
                        acc_log_request("404 Not Found");
                        xlog("L_DBG", "ACC RADIUS: 404 NOT FOUND FOR $si \r\n");
                        sl_send_reply("404", "Not Found");
                        exit;
                };
                append_hf("P-hint: usrloc applied\r\n");

        };



        #if ($scr_ip != 192.168.95.248) {
        #       ds_select_dst("1", "0");
        #       forward();
        #};

        route(1);
}


# Generic Forward
route[1] {
        sip_trace();
        # send it out now; use stateful forwarding as it works reliably
        # even for UDP2TCP
        if (!t_relay()) {
                sl_reply_error();
        };
        exit;
}




failure_route[3]
{
        # authentication reply received?
        xlog("FAILURE ROUTE 3 STARTED  /r/n");
        xlog("AUTHENTICATION REPLY RECEIVED  /r/n");
        if ( t_check_status("401|407") )
        {
                # have we already tried to authenticate?
                if (isflagset(7))
                {
                        t_reply("503","Authentication failed");
                        exit;
                }
                if (uac_auth())
                {
                        # mark that auth was performed
                        setflag(7);
                        # trigger again the failure route
                        t_on_failure("3");
                        # repeat the request with auth response this time
                        append_branch();
                        t_relay();
                }
        }
}



More information about the Devel mailing list