Browse code

sbc: SIP UAS authentication for B leg (uas_auth_bleg_enabled)

Notes:
- All of those profile options must be set
uas_auth_bleg_realm
uas_auth_bleg_user
uas_auth_bleg_pwd

- On realm mismatch, it is not authenticated

- URI is not checked against the Authorization URI

Conflicts:

apps/sbc/SBC.cpp
apps/sbc/SBC.h
apps/sbc/SBCCallProfile.cpp
apps/sbc/SBCCallProfile.h
apps/sbc/etc/transparent.sbcprofile.conf

Conflicts:

apps/sbc/SBC.cpp
apps/sbc/SBC.h
apps/sbc/SBCCallProfile.cpp
apps/sbc/SBCCallProfile.h
apps/sbc/etc/transparent.sbcprofile.conf

Stefan Sayer authored on 01/08/2013 17:10:46
Showing 6 changed files
... ...
@@ -817,4 +817,3 @@ bool SBCFactory::CCRoute(const AmSipRequest& req,
817 817
 
818 818
   return true;
819 819
 }
820
-
... ...
@@ -121,7 +121,7 @@ SBCCallLeg::SBCCallLeg(const SBCCallProfile& call_profile, AmSipDialog* p_dlg,
121 121
 		       AmSipSubscription* p_subs)
122 122
   : CallLeg(p_dlg,p_subs),
123 123
     m_state(BB_Init),
124
-    auth(NULL),
124
+    auth(NULL), auth_di(NULL),
125 125
     call_profile(call_profile),
126 126
     cc_timer_id(SBC_TIMER_ID_CALL_TIMERS_START),
127 127
     ext_cc_timer_id(SBC_TIMER_ID_CALL_TIMERS_END + 1),
... ...
@@ -148,7 +148,7 @@ SBCCallLeg::SBCCallLeg(const SBCCallProfile& call_profile, AmSipDialog* p_dlg,
148 148
 // B leg constructor (from SBCCalleeSession)
149 149
 SBCCallLeg::SBCCallLeg(SBCCallLeg* caller, AmSipDialog* p_dlg,
150 150
 		       AmSipSubscription* p_subs)
151
-  : auth(NULL),
151
+  : auth(NULL), auth_di(NULL),
152 152
     call_profile(caller->getCallProfile()),
153 153
     CallLeg(caller,p_dlg,p_subs),
154 154
     ext_cc_timer_id(SBC_TIMER_ID_CALL_TIMERS_END + 1),
... ...
@@ -197,7 +197,7 @@ SBCCallLeg::SBCCallLeg(SBCCallLeg* caller, AmSipDialog* p_dlg,
197 197
 SBCCallLeg::SBCCallLeg(AmSipDialog* p_dlg, AmSipSubscription* p_subs)
198 198
   : CallLeg(p_dlg,p_subs),
199 199
     m_state(BB_Init),
200
-    auth(NULL),
200
+    auth(NULL),  auth_di(NULL),
201 201
     cc_timer_id(SBC_TIMER_ID_CALL_TIMERS_START),
202 202
     cc_started(false),
203 203
     logger(NULL)
... ...
@@ -331,6 +331,18 @@ void SBCCallLeg::applyBProfile()
331 331
     }
332 332
   }
333 333
 
334
+  if (call_profile.uas_auth_bleg_enabled) {
335
+    AmDynInvokeFactory* fact = AmPlugIn::instance()->getFactory4Di("uac_auth");
336
+    if (NULL != fact) {
337
+      AmDynInvoke* di_inst = fact->getInstance();
338
+      if(NULL != di_inst) {
339
+	setAuthDI(di_inst);
340
+      }
341
+    } else {
342
+      ERROR("B-leg UAS auth enabled (uas_auth_bleg_enabled), but uac_auth module not loaded!\n");
343
+    }
344
+  }
345
+
334 346
   if (call_profile.sst_enabled_value) {
335 347
     if(applySSTCfg(call_profile.sst_b_cfg,NULL) < 0) {
336 348
        throw AmSession::Exception(500, SIP_REPLY_SERVER_INTERNAL_ERROR);
... ...
@@ -519,6 +531,48 @@ void SBCCallLeg::onSipRequest(const AmSipRequest& req) {
519 531
     if ((*i)->onInDialogRequest(this, req) == StopProcessing) return;
520 532
   }
521 533
 
534
+  if (call_profile.uas_auth_bleg_enabled && NULL != auth_di) {
535
+    AmArg di_args, di_ret;
536
+    try {
537
+      DBG("Auth: checking authentication\n");
538
+      di_args.push((AmObject*)&req);
539
+      di_args.push(call_profile.uas_auth_bleg_credentials.realm);
540
+      di_args.push(call_profile.uas_auth_bleg_credentials.user);
541
+      di_args.push(call_profile.uas_auth_bleg_credentials.pwd);
542
+      auth_di->invoke("checkAuth", di_args, di_ret);
543
+
544
+      if (di_ret.size() >= 3) {
545
+	if (di_ret[0].asInt() != 200) {
546
+	  DBG("Auth: replying %u %s - hdrs: '%s'\n",
547
+	      di_ret[0].asInt(), di_ret[1].asCStr(), di_ret[2].asCStr());
548
+	  dlg->reply(req, di_ret[0].asInt(), di_ret[1].asCStr(), NULL, di_ret[2].asCStr());
549
+	  return;
550
+	} else {
551
+	  DBG("Successfully authenticated request.\n");
552
+	}
553
+      } else {
554
+	ERROR("internal: no proper result from checkAuth: '%s'\n", AmArg::print(di_ret).c_str());
555
+      }
556
+
557
+    } catch (const AmDynInvoke::NotImplemented& ni) {
558
+      ERROR("not implemented DI function 'checkAuth'\n");
559
+      dlg->reply(req, 500, SIP_REPLY_SERVER_INTERNAL_ERROR, NULL, "", SIP_FLAGS_VERBATIM);
560
+      return;
561
+    } catch (const AmArg::OutOfBoundsException& oob) {
562
+      ERROR("out of bounds in  DI call 'checkAuth'\n");
563
+      dlg->reply(req, 500, SIP_REPLY_SERVER_INTERNAL_ERROR, NULL, "", SIP_FLAGS_VERBATIM);
564
+      return;
565
+    } catch (const AmArg::TypeMismatchException& oob) {
566
+      ERROR("type mismatch  in  DI call checkAuth\n");
567
+      dlg->reply(req, 500, SIP_REPLY_SERVER_INTERNAL_ERROR, NULL, "", SIP_FLAGS_VERBATIM);
568
+      return;
569
+    } catch (...) {
570
+      ERROR("unexpected Exception  in  DI call checkAuth\n");
571
+      dlg->reply(req, 500, SIP_REPLY_SERVER_INTERNAL_ERROR, NULL, "", SIP_FLAGS_VERBATIM);
572
+      return;
573
+    }
574
+  }
575
+
522 576
   if (fwd && req.method == SIP_METH_INVITE) {
523 577
     DBG("replying 100 Trying to INVITE to be fwd'ed\n");
524 578
     dlg->reply(req, 100, SIP_REPLY_TRYING);
... ...
@@ -69,6 +69,7 @@ class SBCCallLeg : public CallLeg, public CredentialHolder
69 69
 
70 70
   // auth
71 71
   AmSessionEventHandler* auth;
72
+  AmDynInvoke* auth_di;
72 73
 
73 74
   /** Storage for remembered payload IDs from SDP offer to be put correctly into
74 75
    * SDP answer (we avoid with this parsing SDP offer again when processing the
... ...
@@ -156,6 +157,8 @@ class SBCCallLeg : public CallLeg, public CredentialHolder
156 157
   UACAuthCred* getCredentials();
157 158
 
158 159
   void setAuthHandler(AmSessionEventHandler* h) { auth = h; }
160
+  void setAuthDI(AmDynInvoke* di_inst) { auth_di = di_inst; }
161
+
159 162
   bool initCCExtModules(const CCInterfaceListT& cc_module_list, const vector<AmDynInvoke*>& cc_module_di);
160 163
   bool initPendingCCExtModules();
161 164
   void addPendingCCExtModule(const string& cc_name, const string& cc_module, const map<string, string>& cc_values);
... ...
@@ -250,6 +250,11 @@ bool SBCCallProfile::readFromConfiguration(const string& name,
250 250
   auth_aleg_credentials.user = cfg.getParameter("auth_aleg_user");
251 251
   auth_aleg_credentials.pwd = cfg.getParameter("auth_aleg_pwd");
252 252
 
253
+  uas_auth_bleg_enabled = cfg.getParameter("enable_bleg_uas_auth", "no") == "yes";
254
+  uas_auth_bleg_credentials.realm = cfg.getParameter("uas_auth_bleg_realm");
255
+  uas_auth_bleg_credentials.user = cfg.getParameter("uas_auth_bleg_user");
256
+  uas_auth_bleg_credentials.pwd = cfg.getParameter("uas_auth_bleg_pwd");
257
+
253 258
   if (!cfg.getParameter("call_control").empty()) {
254 259
     vector<string> cc_sections = explode(cfg.getParameter("call_control"), ",");
255 260
     for (vector<string>::iterator it =
... ...
@@ -257,7 +262,6 @@ bool SBCCallProfile::readFromConfiguration(const string& name,
257 262
       DBG("reading call control '%s'\n", it->c_str());
258 263
       cc_interfaces.push_back(CCInterface(*it));
259 264
       CCInterface& cc_if = cc_interfaces.back();
260
-
261 265
       cc_if.cc_module = cfg.getParameter(*it + "_module");
262 266
 
263 267
       AmArg mandatory_values;
... ...
@@ -529,6 +533,7 @@ bool SBCCallProfile::readFromConfiguration(const string& name,
529 533
 
530 534
     INFO("SBC:      SIP auth %sabled\n", auth_enabled?"en":"dis");
531 535
     INFO("SBC:      SIP auth for A leg %sabled\n", auth_aleg_enabled?"en":"dis");
536
+    INFO("SBC:      SIP UAS auth for B leg %sabled\n", uas_auth_bleg_enabled?"en":"dis");
532 537
 
533 538
     if (cc_interfaces.size()) {
534 539
       string cc_if_names;
... ...
@@ -814,6 +819,15 @@ bool SBCCallProfile::evaluate(ParamReplacerCtx& ctx,
814 819
 						      "auth_aleg_pwd", req);
815 820
   }
816 821
 
822
+  if (uas_auth_bleg_enabled) {
823
+    uas_auth_bleg_credentials.realm =
824
+      ctx.replaceParameters(uas_auth_bleg_credentials.realm, "uas_auth_bleg_realm", req);
825
+    uas_auth_bleg_credentials.user =
826
+      ctx.replaceParameters(uas_auth_bleg_credentials.user, "uas_auth_bleg_user", req);
827
+    uas_auth_bleg_credentials.pwd =
828
+      ctx.replaceParameters(uas_auth_bleg_credentials.pwd, "uas_auth_bleg_pwd", req);
829
+  }
830
+
817 831
   fix_replaces_inv = ctx.replaceParameters(fix_replaces_inv, "fix_replaces_inv", req);
818 832
   fix_replaces_ref = ctx.replaceParameters(fix_replaces_ref, "fix_replaces_ref", req);
819 833
 
... ...
@@ -172,6 +172,8 @@ struct SBCCallProfile
172 172
 
173 173
   bool auth_aleg_enabled;
174 174
   UACAuthCred auth_aleg_credentials;
175
+  bool uas_auth_bleg_enabled;
176
+  UACAuthCred uas_auth_bleg_credentials;
175 177
 
176 178
   CCInterfaceListT cc_interfaces;
177 179
 
... ...
@@ -89,6 +89,12 @@
89 89
 #auth_aleg_user=$P(au)
90 90
 #auth_aleg_pwd=$P(ap)
91 91
 
92
+## UAS auth for B leg
93
+#uas_auth_bleg_enabled=yes
94
+#uas_auth_bleg_realm=$P(sr)
95
+#uas_auth_bleg_user=$P(su)
96
+#uas_auth_bleg_pwd=$P(sp)
97
+
92 98
 ## call timer
93 99
 #enable_call_timer=yes
94 100
 #call_timer=60