ps.cfg 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568
  1. #
  2. # $Id$
  3. #
  4. # First start SIP-router sample config script with:
  5. # database, accounting, authentication, multi-domain support
  6. # PSTN GW section, named flags, named routes, global-,
  7. # domain- and user-preferences with AVPs
  8. # Several of these features are only here for demonstration purpose
  9. # what can be achieved with the SIP-router config script language.
  10. #
  11. # If you look for a simpler version with a lot less dependencies
  12. # please refer to the ser-basic.cfg file in your SIP-router distribution.
  13. # To get this config running you need to execute the following commands
  14. # with the new serctl (the capital word are just place holders)
  15. # - ser_ctl domain add DOMAINNAME
  16. # - ser_ctl user add USERNAME@DOMAINNAME -p PASSWORD
  17. # If you want to have PID header for your user
  18. # - ser_attr add uid=UID asserted_id="PID"
  19. # If you want to have gateway support
  20. # - ser_db add attr_types name=gw_ip rich_type=string raw_type=2 description="The gateway IP for the default ser.cfg" default_flags=33
  21. # - ser_attr add global gw_ip=GATEWAY-IP
  22. # ----------- global configuration parameters ------------------------
  23. debug=3 # debug level (cmd line: -dddddddddd)
  24. memdbg=10 # memory debug log level
  25. #memlog=10 # memory statistics log level
  26. #log_facility=LOG_LOCAL0 # sets the facility used for logging (see syslog(3))
  27. /* Uncomment these lines to enter debugging mode
  28. fork=no
  29. log_stderror=yes
  30. */
  31. check_via=no # (cmd. line: -v)
  32. dns=no # (cmd. line: -r)
  33. rev_dns=no # (cmd. line: -R)
  34. #port=5060
  35. #children=4
  36. #user=ser
  37. #group=ser
  38. #disable_core=yes #disables core dumping
  39. #open_fd_limit=1024 # sets the open file descriptors limit
  40. #mhomed=yes # usefull for multihomed hosts, small performance penalty
  41. #disable_tcp=yes
  42. #tcp_accept_aliases=yes # accepts the tcp alias via option (see NEWS)
  43. #
  44. # ------------------ module loading ----------------------------------
  45. # load a SQL database for authentication, domains, user AVPs etc.
  46. loadmodule "/home/kubartv/SER/lib/ser/modules/mysql.so"
  47. loadmodule "/home/kubartv/SER/lib/ser/modules/sl.so"
  48. loadmodule "/home/kubartv/SER/lib/ser/modules/tm.so"
  49. loadmodule "/home/kubartv/SER/lib/ser/modules/rr.so"
  50. loadmodule "/home/kubartv/SER/lib/ser/modules/maxfwd.so"
  51. loadmodule "/home/kubartv/SER/lib/ser/modules/usrloc.so"
  52. loadmodule "/home/kubartv/SER/lib/ser/modules/registrar.so"
  53. loadmodule "/home/kubartv/SER/lib/ser/modules/xlog.so"
  54. loadmodule "/home/kubartv/SER/lib/ser/modules/textops.so"
  55. loadmodule "/home/kubartv/SER/lib/ser/modules/ctl.so"
  56. loadmodule "/home/kubartv/SER/lib/ser/modules/fifo.so"
  57. loadmodule "/home/kubartv/SER/lib/ser/modules/auth.so"
  58. loadmodule "/home/kubartv/SER/lib/ser/modules/auth_db.so"
  59. loadmodule "/home/kubartv/SER/lib/ser/modules/gflags.so"
  60. loadmodule "/home/kubartv/SER/lib/ser/modules/domain.so"
  61. loadmodule "/home/kubartv/SER/lib/ser/modules/uri_db.so"
  62. loadmodule "/home/kubartv/SER/lib/ser/modules/avp.so"
  63. loadmodule "/home/kubartv/SER/lib/ser/modules/avp_db.so"
  64. loadmodule "/home/kubartv/SER/lib/ser/modules/acc_db.so"
  65. loadmodule "/home/kubartv/SER/lib/ser/modules/xmlrpc.so"
  66. # presence related modules
  67. loadmodule "/home/kubartv/SER/lib/ser/modules/pa.so"
  68. loadmodule "/home/kubartv/SER/lib/ser/modules/dialog.so"
  69. # ----------------- setting script FLAGS -----------------------------
  70. flags
  71. FLAG_ACC : 1 # include message in accounting
  72. avpflags
  73. dialog_cookie; # handled by rr module
  74. # ----------------- setting module-specific parameters ---------------
  75. # specify the path to you database here
  76. modparam("acc_db|auth_db|avp_db|domain|gflags|usrloc|uri_db", "db_url", "mysql://ser:[email protected]/ser")
  77. # -- usrloc params --
  78. # as we use the database anyway we will use it for usrloc as well
  79. modparam("usrloc", "db_mode", 1)
  80. # -- auth params --
  81. modparam("auth_db", "calculate_ha1", yes)
  82. modparam("auth_db", "password_column", "password")
  83. # -- rr params --
  84. # add value to ;lr param to make some broken UAs happy
  85. modparam("rr", "enable_full_lr", 1)
  86. #
  87. # limit the length of the AVP cookie to only necessary ones
  88. modparam("rr", "cookie_filter", "(account)")
  89. #
  90. # you probably do not want that someone can simply read and change
  91. # the AVP cookie in your Routes, thus should really change this
  92. # secret value below
  93. modparam("rr", "cookie_secret", "MyRRAVPcookiesecret")
  94. # -- gflags params --
  95. # load the global AVPs
  96. modparam("gflags", "load_global_attrs", 1)
  97. # -- domain params --
  98. # load the domain AVPs
  99. modparam("domain", "load_domain_attrs", 1)
  100. # -- ctl params --
  101. # by default ctl listens on unixs:/tmp/ser_ctl if no other address is
  102. # specified in modparams; this is also the default for sercmd
  103. modparam("ctl", "binrpc", "unixs:/tmp/ser_ctl")
  104. # listen on the "standard" fifo for backward compatibility
  105. modparam("ctl", "fifo", "fifo:/tmp/ser_fifo")
  106. # listen on tcp, localhost
  107. #modparam("ctl", "binrpc", "tcp:localhost:2046")
  108. # -- acc_db params --
  109. # failed transactions (=negative responses) should be logged to
  110. modparam("acc_db", "failed_transactions", 1)
  111. # comment the next line if you dont want to have accounting to DB
  112. modparam("acc_db", "log_flag", "FLAG_ACC")
  113. # -- tm params --
  114. # uncomment the following line if you want to avoid that each new reply
  115. # restarts the resend timer (see INBOUND route below)
  116. #modparam("tm", "restart_fr_on_each_reply", "0")
  117. # -- presence modules parameters --
  118. modparam("pa", "use_db", 1)
  119. modparam("pa", "auth", "none")
  120. modparam("pa", "winfo_auth", "none")
  121. modparam("pa", "db_url", "mysql://ser:[email protected]/ser")
  122. # ------------------------- request routing logic -------------------
  123. # main routing logic
  124. route{
  125. # if you have a PSTN gateway just un-comment the follwoing line and
  126. # specify the IP address of it to route calls to it
  127. #$gw_ip = "1.2.3.4"
  128. # first do some initial sanity checks
  129. route(INIT);
  130. # check if the request is routed via Route header or
  131. # needs a Record-Route header
  132. route(RR);
  133. # check if the request belongs to our proxy
  134. route(DOMAIN);
  135. # handle REGISTER requests
  136. route(REGISTRAR);
  137. # handle requests destined for presence server (SUBSCRIBE, PUBLISH, ...)
  138. route(PRESENCE);
  139. # from here on we want to know you is calling
  140. route(AUTHENTICATION);
  141. # check if we should be outbound proxy for a local user
  142. route(OUTBOUND);
  143. # check if the request is for a local user
  144. route(INBOUND);
  145. # here you coud for example try to an ENUM lookup before
  146. # the call gets routed to the PSTN
  147. #route(ENUM);
  148. # lets see if someone wants to call a PSTN number
  149. route(PSTN);
  150. # nothing matched, reject it finally
  151. sl_send_reply("404", "No route matched");
  152. }
  153. route[FORWARD]
  154. {
  155. # here you could decide wether this call needs a RTP relay or not
  156. # send it out now; use stateful forwarding as it works reliably
  157. # even for UDP2TCP
  158. if (!t_relay()) {
  159. sl_reply_error();
  160. };
  161. drop;
  162. }
  163. route[INIT]
  164. {
  165. # as soon as it is save to distinguish HTTP from SIP
  166. # we can un-comment the next line
  167. route(RPC);
  168. # initial sanity checks -- messages with
  169. # max_forwards==0, or excessively long requests
  170. if (!mf_process_maxfwd_header("10")) {
  171. sl_send_reply("483","Too Many Hops");
  172. drop;
  173. };
  174. if (msg:len >= max_len ) {
  175. sl_send_reply("513", "Message too big");
  176. drop;
  177. };
  178. # you could add some NAT detection here for example
  179. # or you cuold call here some of the check from the sanity module
  180. # lets account all initial INVITEs and the BYEs
  181. # if (method=="INVITE" && @to.tag=="" || method=="BYE") {
  182. if (method=="INVITE" && @to.tag=="") {
  183. setflag(FLAG_ACC);
  184. }
  185. }
  186. route[RPC]
  187. {
  188. # allow XMLRPC from localhost
  189. if ((method=="POST" || method=="GET") &&
  190. src_ip==127.0.0.1) {
  191. if (msg:len >= 8192) {
  192. sl_send_reply("513", "Request to big");
  193. drop;
  194. }
  195. # lets see if a module want to answer this
  196. dispatch_rpc();
  197. drop;
  198. }
  199. }
  200. route[RR]
  201. {
  202. # subsequent messages withing a dialog should take the
  203. # path determined by record-routing
  204. if (loose_route()) {
  205. # mark routing logic in request
  206. append_hf("P-hint: rr-enforced\r\n");
  207. # if the Route contained the accounting AVP cookie we
  208. # set the accounting flag for the acc_db module.
  209. # this is more for demonstration purpose as this could
  210. # also be solved without RR cookies.
  211. # Note: this means all in-dialog request will show up in the
  212. # accounting tables, so prepare your accounting software for this ;-)
  213. if ($account == "yes") {
  214. setflag(FLAG_ACC);
  215. }
  216. # for broken devices which overwrite their Route's with each
  217. # (not present) RR from within dialog requests it is better
  218. # to repeat the RRing
  219. # and if we call rr after loose_route the AVP cookies are restored
  220. # automatically :)
  221. record_route();
  222. route(FORWARD);
  223. } else if (!method=="REGISTER") {
  224. # we record-route all messages -- to make sure that
  225. # subsequent messages will go through our proxy; that's
  226. # particularly good if upstream and downstream entities
  227. # use different transport protocol
  228. # if the inital INVITE got the ACC flag store this in
  229. # an RR AVP cookie. this is more for demonstration purpose
  230. if (isflagset(FLAG_ACC)) {
  231. $account = "yes";
  232. setavpflag($account, "dialog_cookie");
  233. }
  234. record_route();
  235. }
  236. }
  237. route[DOMAIN]
  238. {
  239. # check if the caller is from a local domain
  240. lookup_domain("$fd", "@from.uri.host");
  241. # check if the callee is at a local domain [presence: we can not use @ruri
  242. # here because in consequent SUBSCRIBEs will be there our IP and not the
  243. # domain]
  244. lookup_domain("$td", "@to.uri.host");
  245. # we dont know the domain of the caller and also not
  246. # the domain of the callee -> somone uses our proxy as
  247. # a relay
  248. if (!$t.did && !$f.did) {
  249. sl_send_reply("403", "Relaying Forbidden");
  250. drop;
  251. }
  252. }
  253. route[REGISTRAR]
  254. {
  255. # if the request is a REGISTER lets take care of it
  256. if (method=="REGISTER") {
  257. # check if the REGISTER if for one of our local domains
  258. if (!$t.did) {
  259. sl_send_reply("403", "Register forwarding forbidden");
  260. drop;
  261. }
  262. # we want only authenticated users to be registered
  263. # if (!www_authenticate("$fd.digest_realm", "credentials")) {
  264. # if ($? == -2) {
  265. # sl_send_reply("500", "Internal Server Error");
  266. # } else if ($? == -3) {
  267. # sl_send_reply("400", "Bad Request");
  268. # } else {
  269. # if ($digest_challenge) {
  270. # append_to_reply("%$digest_challenge");
  271. # }
  272. # sl_send_reply("401", "Unauthorized");
  273. # }
  274. # drop;
  275. # };
  276. # check if the authenticated user is the same as the target user
  277. if (!lookup_user("$tu.uid", "@to.uri")) {
  278. sl_send_reply("404", "Unknown user in To");
  279. drop;
  280. }
  281. if ($f.uid != $t.uid) {
  282. sl_send_reply("403", "Authentication and To-Header mismatch");
  283. drop;
  284. }
  285. # check if the authenticated user is the same as the request originator
  286. # you may uncomment it if you care, what uri is in From header
  287. #if (!lookup_user("$fu.uid", "@from.uri")) {
  288. # sl_send_reply("404", "Unknown user in From");
  289. # drop;
  290. #}
  291. #if ($fu.uid != $tu.uid) {
  292. # sl_send_reply("403", "Authentication and From-Header mismatch");
  293. # drop;
  294. #}
  295. # everyhting is fine so lets store the binding
  296. save_contacts("location");
  297. drop;
  298. };
  299. }
  300. route[AUTHENTICATION]
  301. {
  302. if (method=="CANCEL" || method=="ACK") {
  303. # you are not allowed to challenge these methods
  304. break;
  305. }
  306. # requests from non-local to local domains should be permitted
  307. # remove this if you want a walled garden
  308. if (! $f.did) {
  309. break;
  310. }
  311. # as gateways are usually not able to authenticate for their
  312. # requests you will have trust them base on some other information
  313. # like the source IP address. WARNING: if at all this is only safe
  314. # in a local network!!!
  315. #if (src_ip==a.b.c.d) {
  316. # break;
  317. #}
  318. if (!proxy_authenticate("$fd.digest_realm", "credentials")) {
  319. if ($? == -2) {
  320. sl_send_reply("500", "Internal Server Error");
  321. } else if ($? == -3) {
  322. sl_send_reply("400", "Bad Request");
  323. } else {
  324. if ($digest_challenge) {
  325. append_to_reply("%$digest_challenge");
  326. }
  327. sl_send_reply("407", "Proxy Authentication Required");
  328. }
  329. drop;
  330. }
  331. # check if the UID from the authentication meets the From header
  332. $authuid = $uid;
  333. if (!lookup_user("$fu.uid", "@from.uri")) {
  334. del_attr("$uid");
  335. }
  336. if ($fu.uid != $fr.authuid) {
  337. sl_send_reply("403", "Fake Identity");
  338. drop;
  339. }
  340. # load the user AVPs (preferences) of the caller, e.g. for RPID header
  341. load_attrs("$fu", "$f.uid");
  342. }
  343. route[OUTBOUND]
  344. {
  345. # if a local user calls to a foreign domain we play outbound proxy for him
  346. # comment this out if you want a walled garden
  347. if ($f.did && ! $t.did) {
  348. append_hf("P-hint: outbound\r\n");
  349. route(FORWARD);
  350. }
  351. }
  352. route[INBOUND]
  353. {
  354. # lets see if know the callee
  355. if (lookup_user("$tu.uid", "@ruri")) {
  356. # load the preferences of the callee to have his timeout values loaded
  357. load_attrs("$tu", "$t.uid");
  358. # if you want to know if the callee username was an alias
  359. # check it like this
  360. #if (! $tu.uri_canonical) {
  361. # if the alias URI has different AVPs/preferences
  362. # you can load them into the URI track like this
  363. #load_attrs("$tr", "@ruri");
  364. #}
  365. # native SIP destinations are handled using our USRLOC DB
  366. if (lookup_contacts("location")) {
  367. append_hf("P-hint: usrloc applied\r\n");
  368. # we set the TM module timers according to the prefences
  369. # of the callee (avoid too long ringing of his phones)
  370. # Note1: timer values have to be in ms now!
  371. # Note2: this makes even more sense if you switch to a voicemail
  372. # in a FAILURE route
  373. if ($t.fr_inv_timer) {
  374. if ($t.fr_timer) {
  375. t_set_fr("$t.fr_inv_timer", "$t.fr_timer");
  376. } else {
  377. t_set_fr("$t.fr_inv_timer");
  378. }
  379. }
  380. route(FORWARD);
  381. } else {
  382. sl_send_reply("480", "User temporarily not available");
  383. drop;
  384. }
  385. };
  386. }
  387. route[PSTN]
  388. {
  389. # Only if the AVP 'gw_ip' is set and the request URI contains
  390. # only a number we consider sending this to the PSTN GW.
  391. # Only users from a local domain are permitted to make calls.
  392. # Additionally you might want to check the acl AVP to verify
  393. # that the user is allowed to make such expensives calls.
  394. if ($f.did && $gw_ip &&
  395. uri=~"sips?:\+?[0-9]{3,18}@.*") {
  396. # probably you need to convert the number in the request
  397. # URI according to the requirements of your gateway here
  398. # if an AVP 'asserted_id' is set we insert an RPID header
  399. if ($asserted_id) {
  400. xlset_attr("$rpidheader", "<sip:%$asserted_id@%@ruri.host>;screen=yes");
  401. replace_attr_hf("Remote-Party-ID", "$rpidheader");
  402. }
  403. # just replace the domain part of the RURI with the
  404. # value from the AVP and send it out
  405. attr2uri("$gw_ip", "domain");
  406. route(FORWARD);
  407. }
  408. }
  409. route[PRES_AUTHENTICATE]
  410. {
  411. # we want only authenticated users to be registered
  412. if (!www_authenticate("$fd.digest_realm", "credentials")) {
  413. if ($? == -2) {
  414. sl_send_reply("500", "Internal Server Error");
  415. } else if ($? == -3) {
  416. sl_send_reply("400", "Bad Request");
  417. } else {
  418. if ($digest_challenge) {
  419. append_to_reply("%$digest_challenge");
  420. }
  421. sl_send_reply("401", "Unauthorized");
  422. }
  423. drop;
  424. };
  425. # check if the UID from the authentication meets the From header
  426. $authuid = $uid;
  427. if (!lookup_user("$fu.uid", "@from.uri")) {
  428. del_attr("$uid");
  429. }
  430. if ($fu.uid != $fr.authuid) {
  431. sl_send_reply("403", "Fake Identity");
  432. drop;
  433. }
  434. }
  435. route[RLS]
  436. {
  437. # to be done ... ;-)
  438. break;
  439. }
  440. route[PRESENCE]
  441. {
  442. # if the request is one of presence messages lets take care of it
  443. if (!((method=="SUBSCRIBE") || (method=="PUBLISH"))) {
  444. # it is not presence related message let it be
  445. break;
  446. }
  447. # check if the request is for one of our local domains
  448. if (!$t.did) {
  449. xlog("L_ERR", "Unknown domain in presence related message\n");
  450. sl_send_reply("403", "Will not forward presence");
  451. drop;
  452. }
  453. # authenticate the user in From using www_authenticate
  454. # route(PRES_AUTHENTICATE);
  455. if (!t_newtran()) {
  456. sl_send_reply("500", "Internal error (t_newtran)");
  457. drop;
  458. }
  459. if (!lookup_user("$tu.uid", "@to.uri")) {
  460. if (method=="SUBSCRIBE") {
  461. # SUBSCRIBE to nonexisting user -> try to handle it
  462. # with RLS
  463. route(RLS);
  464. }
  465. t_reply("404", "Unknown user in To");
  466. drop;
  467. }
  468. if (method=="SUBSCRIBE") {
  469. handle_subscription("registrar");
  470. }
  471. if (method=="PUBLISH") {
  472. handle_publish("registrar");
  473. }
  474. drop;
  475. }