diff options
Diffstat (limited to 'OpenSim/Region/OptionalModules/Avatar/Voice')
-rw-r--r-- | OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | 296 |
1 files changed, 275 insertions, 21 deletions
diff --git a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs index abe7594..513d169 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Voice/FreeSwitchVoice/FreeSwitchVoiceModule.cs | |||
@@ -28,7 +28,9 @@ | |||
28 | using System; | 28 | using System; |
29 | using System.IO; | 29 | using System.IO; |
30 | using System.Net; | 30 | using System.Net; |
31 | using System.Net.Security; | ||
31 | using System.Web; | 32 | using System.Web; |
33 | using System.Security.Cryptography.X509Certificates; | ||
32 | using System.Text; | 34 | using System.Text; |
33 | using System.Xml; | 35 | using System.Xml; |
34 | using System.Collections; | 36 | using System.Collections; |
@@ -47,6 +49,7 @@ using OpenSim.Region.Framework.Scenes; | |||
47 | using Caps = OpenSim.Framework.Communications.Capabilities.Caps; | 49 | using Caps = OpenSim.Framework.Communications.Capabilities.Caps; |
48 | using System.Text.RegularExpressions; | 50 | using System.Text.RegularExpressions; |
49 | 51 | ||
52 | |||
50 | namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice | 53 | namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice |
51 | { | 54 | { |
52 | public class FreeSwitchVoiceModule : IRegionModule | 55 | public class FreeSwitchVoiceModule : IRegionModule |
@@ -56,6 +59,8 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice | |||
56 | private static readonly ILog m_log = | 59 | private static readonly ILog m_log = |
57 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 60 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
58 | 61 | ||
62 | private const bool UseProxy = false; | ||
63 | |||
59 | // Capability string prefixes | 64 | // Capability string prefixes |
60 | private static readonly string m_parcelVoiceInfoRequestPath = "0007/"; | 65 | private static readonly string m_parcelVoiceInfoRequestPath = "0007/"; |
61 | private static readonly string m_provisionVoiceAccountRequestPath = "0008/"; | 66 | private static readonly string m_provisionVoiceAccountRequestPath = "0008/"; |
@@ -95,7 +100,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice | |||
95 | 100 | ||
96 | private FreeSwitchDirectory m_FreeSwitchDirectory; | 101 | private FreeSwitchDirectory m_FreeSwitchDirectory; |
97 | private FreeSwitchDialplan m_FreeSwitchDialplan; | 102 | private FreeSwitchDialplan m_FreeSwitchDialplan; |
103 | |||
104 | private readonly Dictionary<string, string> m_UUIDName = new Dictionary<string, string>(); | ||
98 | 105 | ||
106 | |||
99 | private IConfig m_config; | 107 | private IConfig m_config; |
100 | 108 | ||
101 | public void Initialise(Scene scene, IConfigSource config) | 109 | public void Initialise(Scene scene, IConfigSource config) |
@@ -159,22 +167,42 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice | |||
159 | // set up http request handlers for | 167 | // set up http request handlers for |
160 | // - prelogin: viv_get_prelogin.php | 168 | // - prelogin: viv_get_prelogin.php |
161 | // - signin: viv_signin.php | 169 | // - signin: viv_signin.php |
162 | scene.CommsManager.HttpServer.AddHTTPHandler(String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix), | 170 | // - buddies: viv_buddy.php |
163 | FreeSwitchSLVoiceGetPreloginHTTPHandler); | 171 | // - ???: viv_watcher.php |
164 | 172 | // - signout: viv_signout.php | |
165 | // RestStreamHandler h = new | 173 | if (UseProxy) |
166 | // RestStreamHandler("GET", | 174 | { |
167 | // String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix), FreeSwitchSLVoiceGetPreloginHTTPHandler); | 175 | scene.CommsManager.HttpServer.AddHTTPHandler(String.Format("{0}/", m_freeSwitchAPIPrefix), |
168 | // scene.CommsManager.HttpServer.AddStreamHandler(h); | 176 | ForwardProxyRequest); |
177 | } | ||
178 | else | ||
179 | { | ||
180 | scene.CommsManager.HttpServer.AddHTTPHandler(String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix), | ||
181 | FreeSwitchSLVoiceGetPreloginHTTPHandler); | ||
182 | |||
183 | // RestStreamHandler h = new | ||
184 | // RestStreamHandler("GET", | ||
185 | // String.Format("{0}/viv_get_prelogin.php", m_freeSwitchAPIPrefix), FreeSwitchSLVoiceGetPreloginHTTPHandler); | ||
186 | // scene.CommsManager.HttpServer.AddStreamHandler(h); | ||
187 | |||
188 | |||
189 | |||
190 | scene.CommsManager.HttpServer.AddHTTPHandler(String.Format("{0}/viv_signin.php", m_freeSwitchAPIPrefix), | ||
191 | FreeSwitchSLVoiceSigninHTTPHandler); | ||
192 | |||
193 | // set up http request handlers to provide | ||
194 | // on-demand FreeSwitch configuration to | ||
195 | // FreeSwitch's mod_curl_xml | ||
196 | scene.CommsManager.HttpServer.AddHTTPHandler(String.Format("{0}/freeswitch-config", m_freeSwitchAPIPrefix), | ||
197 | FreeSwitchConfigHTTPHandler); | ||
198 | |||
199 | scene.CommsManager.HttpServer.AddHTTPHandler(String.Format("{0}/viv_buddy.php", m_freeSwitchAPIPrefix), | ||
200 | FreeSwitchSLVoiceBuddyHTTPHandler); | ||
201 | } | ||
169 | 202 | ||
170 | scene.CommsManager.HttpServer.AddHTTPHandler(String.Format("{0}/viv_signin.php", m_freeSwitchAPIPrefix), | 203 | |
171 | FreeSwitchSLVoiceSigninHTTPHandler); | 204 | |
172 | 205 | ||
173 | // set up http request handlers to provide | ||
174 | // on-demand FreeSwitch configuration to | ||
175 | // FreeSwitch's mod_curl_xml | ||
176 | scene.CommsManager.HttpServer.AddHTTPHandler(String.Format("{0}/freeswitch-config", m_freeSwitchAPIPrefix), | ||
177 | FreeSwitchConfigHTTPHandler); | ||
178 | 206 | ||
179 | m_log.InfoFormat("[FreeSwitchVoice] using FreeSwitch server {0}", m_freeSwitchRealm); | 207 | m_log.InfoFormat("[FreeSwitchVoice] using FreeSwitch server {0}", m_freeSwitchRealm); |
180 | 208 | ||
@@ -203,7 +231,24 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice | |||
203 | OnRegisterCaps(scene, agentID, caps); | 231 | OnRegisterCaps(scene, agentID, caps); |
204 | }; | 232 | }; |
205 | 233 | ||
206 | 234 | try | |
235 | { | ||
236 | ServicePointManager.ServerCertificateValidationCallback += CustomCertificateValidation; | ||
237 | } | ||
238 | catch (NotImplementedException) | ||
239 | { | ||
240 | try | ||
241 | { | ||
242 | #pragma warning disable 0612, 0618 | ||
243 | // Mono does not implement the ServicePointManager.ServerCertificateValidationCallback yet! Don't remove this! | ||
244 | ServicePointManager.CertificatePolicy = new MonoCert(); | ||
245 | #pragma warning restore 0612, 0618 | ||
246 | } | ||
247 | catch (Exception) | ||
248 | { | ||
249 | m_log.Error("[FreeSwitchVoice]: Certificate validation handler change not supported. You may get ssl certificate validation errors teleporting from your region to some SSL regions."); | ||
250 | } | ||
251 | } | ||
207 | 252 | ||
208 | } | 253 | } |
209 | } | 254 | } |
@@ -290,6 +335,14 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice | |||
290 | UUID agentID, Caps caps) | 335 | UUID agentID, Caps caps) |
291 | { | 336 | { |
292 | ScenePresence avatar = scene.GetScenePresence(agentID); | 337 | ScenePresence avatar = scene.GetScenePresence(agentID); |
338 | if (avatar == null) | ||
339 | { | ||
340 | System.Threading.Thread.Sleep(2000); | ||
341 | avatar = scene.GetScenePresence(agentID); | ||
342 | |||
343 | if (avatar == null) | ||
344 | return "<llsd>undef</llsd>"; | ||
345 | } | ||
293 | string avatarName = avatar.Name; | 346 | string avatarName = avatar.Name; |
294 | 347 | ||
295 | try | 348 | try |
@@ -305,8 +358,20 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice | |||
305 | // FreeSwitch is later going to come and ask us for | 358 | // FreeSwitch is later going to come and ask us for |
306 | // those | 359 | // those |
307 | agentname = agentname.Replace('+', '-').Replace('/', '_'); | 360 | agentname = agentname.Replace('+', '-').Replace('/', '_'); |
308 | 361 | ||
309 | // LLSDVoiceAccountResponse voiceAccountResponse = | 362 | lock (m_UUIDName) |
363 | { | ||
364 | if (m_UUIDName.ContainsKey(agentname)) | ||
365 | { | ||
366 | m_UUIDName[agentname] = avatarName; | ||
367 | } | ||
368 | else | ||
369 | { | ||
370 | m_UUIDName.Add(agentname, avatarName); | ||
371 | } | ||
372 | } | ||
373 | |||
374 | // LLSDVoiceAccountResponse voiceAccountResponse = | ||
310 | // new LLSDVoiceAccountResponse(agentname, password, m_freeSwitchRealm, "http://etsvc02.hursley.ibm.com/api"); | 375 | // new LLSDVoiceAccountResponse(agentname, password, m_freeSwitchRealm, "http://etsvc02.hursley.ibm.com/api"); |
311 | LLSDVoiceAccountResponse voiceAccountResponse = | 376 | LLSDVoiceAccountResponse voiceAccountResponse = |
312 | new LLSDVoiceAccountResponse(agentname, password, m_freeSwitchRealm, | 377 | new LLSDVoiceAccountResponse(agentname, password, m_freeSwitchRealm, |
@@ -433,6 +498,57 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice | |||
433 | return "<llsd>true</llsd>"; | 498 | return "<llsd>true</llsd>"; |
434 | } | 499 | } |
435 | 500 | ||
501 | public Hashtable ForwardProxyRequest(Hashtable request) | ||
502 | { | ||
503 | m_log.Debug("[PROXYING]: -------------------------------proxying request"); | ||
504 | Hashtable response = new Hashtable(); | ||
505 | response["content_type"] = "text/xml"; | ||
506 | response["str_response_string"] = ""; | ||
507 | response["int_response_code"] = 200; | ||
508 | |||
509 | string forwardaddress = "https://www.bhr.vivox.com/api2/"; | ||
510 | string body = (string)request["body"]; | ||
511 | string method = (string) request["http-method"]; | ||
512 | string contenttype = (string) request["content-type"]; | ||
513 | string uri = (string) request["uri"]; | ||
514 | uri = uri.Replace("/api/", ""); | ||
515 | forwardaddress += uri; | ||
516 | |||
517 | |||
518 | string fwdresponsestr = ""; | ||
519 | int fwdresponsecode = 200; | ||
520 | string fwdresponsecontenttype = "text/xml"; | ||
521 | |||
522 | |||
523 | HttpWebRequest forwardreq = (HttpWebRequest)WebRequest.Create(forwardaddress); | ||
524 | forwardreq.Method = method; | ||
525 | forwardreq.ContentType = contenttype; | ||
526 | forwardreq.KeepAlive = false; | ||
527 | |||
528 | if (method == "POST") | ||
529 | { | ||
530 | byte[] contentreq = Encoding.UTF8.GetBytes(body); | ||
531 | forwardreq.ContentLength = contentreq.Length; | ||
532 | Stream reqStream = forwardreq.GetRequestStream(); | ||
533 | reqStream.Write(contentreq, 0, contentreq.Length); | ||
534 | reqStream.Close(); | ||
535 | } | ||
536 | |||
537 | HttpWebResponse fwdrsp = (HttpWebResponse)forwardreq.GetResponse(); | ||
538 | Encoding encoding = Encoding.UTF8; | ||
539 | StreamReader fwdresponsestream = new StreamReader(fwdrsp.GetResponseStream(), encoding); | ||
540 | fwdresponsestr = fwdresponsestream.ReadToEnd(); | ||
541 | fwdresponsecontenttype = fwdrsp.ContentType; | ||
542 | fwdresponsecode = (int)fwdrsp.StatusCode; | ||
543 | fwdresponsestream.Close(); | ||
544 | |||
545 | response["content_type"] = fwdresponsecontenttype; | ||
546 | response["str_response_string"] = fwdresponsestr; | ||
547 | response["int_response_code"] = fwdresponsecode; | ||
548 | |||
549 | return response; | ||
550 | } | ||
551 | |||
436 | 552 | ||
437 | public Hashtable FreeSwitchSLVoiceGetPreloginHTTPHandler(Hashtable request) | 553 | public Hashtable FreeSwitchSLVoiceGetPreloginHTTPHandler(Hashtable request) |
438 | { | 554 | { |
@@ -468,22 +584,139 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice | |||
468 | return response; | 584 | return response; |
469 | } | 585 | } |
470 | 586 | ||
587 | public Hashtable FreeSwitchSLVoiceBuddyHTTPHandler(Hashtable request) | ||
588 | { | ||
589 | Hashtable response = new Hashtable(); | ||
590 | response["int_response_code"] = 200; | ||
591 | response["str_response_string"] = string.Empty; | ||
592 | response["content-type"] = "text/xml"; | ||
593 | |||
594 | Hashtable requestBody = parseRequestBody((string)request["body"]); | ||
595 | |||
596 | if (!requestBody.ContainsKey("auth_token")) | ||
597 | return response; | ||
598 | |||
599 | string auth_token = (string)requestBody["auth_token"]; | ||
600 | string[] auth_tokenvals = auth_token.Split(':'); | ||
601 | string username = auth_tokenvals[0]; | ||
602 | int strcount = 0; | ||
603 | |||
604 | string[] ids = new string[strcount]; | ||
605 | |||
606 | int iter = -1; | ||
607 | lock (m_UUIDName) | ||
608 | { | ||
609 | strcount = m_UUIDName.Count; | ||
610 | ids = new string[strcount]; | ||
611 | foreach (string s in m_UUIDName.Keys) | ||
612 | { | ||
613 | iter++; | ||
614 | ids[iter] = s; | ||
615 | } | ||
616 | } | ||
617 | StringBuilder resp = new StringBuilder(); | ||
618 | resp.Append("<?xml version=\"1.0\" encoding=\"iso-8859-1\" ?><response xmlns=\"http://www.vivox.com\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation= \"/xsd/buddy_list.xsd\">"); | ||
619 | |||
620 | resp.Append(string.Format(@"<level0> | ||
621 | <status>OK</status> | ||
622 | <cookie_name>lib_session</cookie_name> | ||
623 | <cookie>{0}</cookie> | ||
624 | <auth_token>{0}</auth_token> | ||
625 | <body> | ||
626 | <buddies>",auth_token)); | ||
627 | /* | ||
628 | <cookie_name>lib_session</cookie_name> | ||
629 | <cookie>{0}:{1}:9303959503950::</cookie> | ||
630 | <auth_token>{0}:{1}:9303959503950::</auth_token> | ||
631 | */ | ||
632 | for (int i=0;i<ids.Length;i++) | ||
633 | { | ||
634 | DateTime currenttime = DateTime.Now; | ||
635 | string dt = currenttime.ToString("yyyy-MM-dd HH:mm:ss.0zz"); | ||
636 | resp.Append( | ||
637 | string.Format(@"<level3> | ||
638 | <bdy_id>{1}</bdy_id> | ||
639 | <bdy_data></bdy_data> | ||
640 | <bdy_uri>sip:{0}@{2}</bdy_uri> | ||
641 | <bdy_nickname>{0}</bdy_nickname> | ||
642 | <bdy_username>{0}</bdy_username> | ||
643 | <bdy_domain>{2}</bdy_domain> | ||
644 | <bdy_status>A</bdy_status> | ||
645 | <modified_ts>{3}</modified_ts> | ||
646 | <b2g_group_id></b2g_group_id> | ||
647 | </level3>", ids[i],i,m_freeSwitchRealm,dt)); | ||
648 | } | ||
649 | |||
650 | |||
651 | |||
652 | resp.Append("</buddies><groups></groups></body></level0></response>"); | ||
653 | |||
654 | response["str_response_string"] = resp.ToString(); | ||
655 | Regex normalizeEndLines = new Regex(@"\r\n", RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.Multiline); | ||
656 | |||
657 | m_log.DebugFormat("[FREESWITCH]: {0}", normalizeEndLines.Replace((string)response["str_response_string"],"")); | ||
658 | return response; | ||
659 | } | ||
660 | |||
471 | public Hashtable FreeSwitchSLVoiceSigninHTTPHandler(Hashtable request) | 661 | public Hashtable FreeSwitchSLVoiceSigninHTTPHandler(Hashtable request) |
472 | { | 662 | { |
473 | m_log.Debug("[FreeSwitchVoice] FreeSwitchSLVoiceSigninHTTPHandler called"); | 663 | m_log.Debug("[FreeSwitchVoice] FreeSwitchSLVoiceSigninHTTPHandler called"); |
474 | 664 | string requestbody = (string)request["body"]; | |
665 | string uri = (string)request["uri"]; | ||
666 | string contenttype = (string)request["content-type"]; | ||
667 | |||
668 | Hashtable requestBody = parseRequestBody((string)request["body"]); | ||
669 | |||
670 | string pwd = (string) requestBody["pwd"]; | ||
671 | string userid = (string) requestBody["userid"]; | ||
672 | |||
673 | string avatarName = string.Empty; | ||
674 | int pos = -1; | ||
675 | lock (m_UUIDName) | ||
676 | { | ||
677 | if (m_UUIDName.ContainsKey(userid)) | ||
678 | { | ||
679 | avatarName = m_UUIDName[userid]; | ||
680 | foreach (string s in m_UUIDName.Keys) | ||
681 | { | ||
682 | pos++; | ||
683 | if (s == userid) | ||
684 | break; | ||
685 | |||
686 | } | ||
687 | } | ||
688 | } | ||
689 | |||
690 | m_log.DebugFormat("[FreeSwitchVoice]: AUTH, URI: {0}, Content-Type:{1}, Body{2}", uri, contenttype, | ||
691 | requestbody); | ||
475 | Hashtable response = new Hashtable(); | 692 | Hashtable response = new Hashtable(); |
476 | response["str_response_string"] = @"<response xsi:schemaLocation=""/xsd/error.xsd""> | 693 | response["str_response_string"] = string.Format(@"<response xsi:schemaLocation=""/xsd/signin.xsd""> |
477 | <level0> | 694 | <level0> |
478 | <status>OK</status> | 695 | <status>OK</status> |
479 | <body> | 696 | <body> |
480 | <code>200</code> | 697 | <code>200</code> |
698 | <cookie_name>lib_session</cookie_name> | ||
699 | <cookie>{0}:{1}:9303959503950::</cookie> | ||
700 | <auth_token>{0}:{1}:9303959503950::</auth_token> | ||
701 | <primary>1</primary> | ||
702 | <account_id>{1}</account_id> | ||
703 | <displayname>{2}</displayname> | ||
481 | <msg>auth successful</msg> | 704 | <msg>auth successful</msg> |
482 | </body> | 705 | </body> |
483 | </level0> | 706 | </level0> |
484 | </response>"; | 707 | </response>", userid, pos, avatarName); |
708 | |||
485 | response["int_response_code"] = 200; | 709 | response["int_response_code"] = 200; |
486 | return response; | 710 | return response; |
711 | /* | ||
712 | <level0> | ||
713 | <status>OK</status><body><status>Ok</status><cookie_name>lib_session</cookie_name> | ||
714 | * <cookie>xMj1QJSc7TA-G7XqcW6QXAg==:1290551700:050d35c6fef96f132f780d8039ff7592::</cookie> | ||
715 | * <auth_token>xMj1QJSc7TA-G7XqcW6QXAg==:1290551700:050d35c6fef96f132f780d8039ff7592::</auth_token> | ||
716 | * <primary>1</primary> | ||
717 | * <account_id>7449</account_id> | ||
718 | * <displayname>Teravus Ousley</displayname></body></level0> | ||
719 | */ | ||
487 | } | 720 | } |
488 | 721 | ||
489 | 722 | ||
@@ -569,5 +802,26 @@ namespace OpenSim.Region.OptionalModules.Avatar.Voice.FreeSwitchVoice | |||
569 | 802 | ||
570 | return channelUri; | 803 | return channelUri; |
571 | } | 804 | } |
805 | |||
806 | private static bool CustomCertificateValidation(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors error) | ||
807 | { | ||
808 | //if (cert.Subject == "E=root@lindenlab.com, CN=*.vaak.lindenlab.com, O=\"Linden Lab, Inc.\", L=San Francisco, S=California, C=US") | ||
809 | //{ | ||
810 | return true; | ||
811 | //} | ||
812 | |||
813 | //return false; | ||
814 | } | ||
815 | } | ||
816 | public class MonoCert : ICertificatePolicy | ||
817 | { | ||
818 | #region ICertificatePolicy Members | ||
819 | |||
820 | public bool CheckValidationResult(ServicePoint srvPoint, X509Certificate certificate, WebRequest request, int certificateProblem) | ||
821 | { | ||
822 | return true; | ||
823 | } | ||
824 | |||
825 | #endregion | ||
572 | } | 826 | } |
573 | } | 827 | } |