Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F7313314
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
18 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/config.ini.sample b/config.ini.sample
index 26aaf6d..631b8ae 100644
--- a/config.ini.sample
+++ b/config.ini.sample
@@ -1,84 +1,82 @@
; SylkServer configuration file
[Server]
; The following settings are the default used by the software, uncomment
; them only if you want to make changes
; default_application = conference
; Map user part of the Request URI to a specific application
; application_map = 123:conference,test:irc-conference
; trace_dir = /var/log/sylkserver
; trace_sip = False
; trace_msrp = False
; trace_notifications = False
; TLS can be used for encryption of SIP signaling and MSRP media. TLS is
; disabled by default. To enable TLS, you must have a valid X.509
; certificate and configure it below, then set the local_tls_port in the SIP
; section and use_tls in MSRP section
; The X.509 Certificate Authorities file
; ca_file = /etc/sylkserver/tls/ca.crt
; The file containing X.509 certificate and private key in unencrypted format
; certificate = /etc/sylkserver/tls/sylkserver.crt
; verify_server = False
[SIP]
; SIP transport settings
; IP address used for SIP signaling; empty string or any means listen on interface used
; by the default route
; local_ip =
; Ports used for SIP transports, if not set to any value the transport will be disabled
; local_udp_port = 5060
; local_tcp_port = 5060
; local_tls_port =
; If set all outbound SIP requests will be sent through this SIP proxy
; outbound_proxy =
; A comma-separated list of hosts or networks to trust.
; The elements can be an IP address in CIDR format, a
; hostname or an IP address (in the latter 2 a mask of 32
; is assumed), or the special keywords 'any' and 'none'
; (being equivalent to 0.0.0.0/0 and 0.0.0.0/32
; respectively). It defaults to 'any'.
; trusted_peers =
[MSRP]
; MSRP transport settings
; Indicate if ACM should be offered. If set to true (default) the server will offer 'actpass'
-; for outbound sessions, alowing clients to connect to the server without using a MSRP relay
+; for outbound sessions
; use_acm = True
-; By default MSRP media is using TCP, to enable TLS you must configure a
-; X.509 certificate in the server section and enable it here
; use_tls = False
[RTP]
; RTP transport settings
; Allowed codec list, valid values: G722, speex, PCMU, PCMA, iLBC, GSM
; audio_codecs = G722,speex,PCMU,PCMA
; Port range used for RTP
; port_range = 50000:50500
; SRTP valid values: disabled, mandatory, optional
; srtp_encryption = optional
; RTP stream timeout, session will be disconnected after this value
; timeout = 30
diff --git a/sylk/configuration/__init__.py b/sylk/configuration/__init__.py
index 1e478b7..d175e93 100644
--- a/sylk/configuration/__init__.py
+++ b/sylk/configuration/__init__.py
@@ -1,70 +1,69 @@
# Copyright (C) 2010-2011 AG Projects. See LICENSE for details.
#
from application.configuration import ConfigSection, ConfigSetting
from application.configuration.datatypes import NetworkRangeList, StringList
from application.system import host
from sipsimple.configuration.datatypes import NonNegativeInteger, SRTPEncryption
from sylk import configuration_filename
from sylk.configuration.datatypes import AudioCodecs, IPAddress, Port, PortRange, SIPProxyAddress
from sylk.tls import Certificate, PrivateKey
class ServerConfig(ConfigSection):
__cfgfile__ = configuration_filename
__section__ = 'Server'
ca_file = ConfigSetting(type=str, value='/etc/sylkserver/tls/ca.crt')
certificate = ConfigSetting(type=str, value='/etc/sylkserver/tls/sylkserver.crt')
verify_server = False
default_application = 'conference'
application_map = ConfigSetting(type=StringList, value='')
trace_dir = ConfigSetting(type=str, value='/var/log/sylkserver')
trace_sip = False
trace_msrp = False
trace_notifications = False
class SIPConfig(ConfigSection):
__cfgfile__ = configuration_filename
__section__ = 'SIP'
local_ip = ConfigSetting(type=IPAddress, value=host.default_ip)
local_udp_port = ConfigSetting(type=Port, value=5060)
local_tcp_port = ConfigSetting(type=Port, value=5060)
local_tls_port = ConfigSetting(type=Port, value=None)
outbound_proxy = ConfigSetting(type=SIPProxyAddress, value=None)
trusted_peers = ConfigSetting(type=NetworkRangeList, value=NetworkRangeList('any'))
class MSRPConfig(ConfigSection):
__cfgfile__ = configuration_filename
__section__ = 'MSRP'
- use_acm = True
use_tls = False
class RTPConfig(ConfigSection):
__cfgfile__ = configuration_filename
__section__ = 'RTP'
audio_codecs = ConfigSetting(type=AudioCodecs, value=None)
port_range = ConfigSetting(type=PortRange, value=PortRange('50000:50500'))
srtp_encryption = ConfigSetting(type=SRTPEncryption, value='optional')
timeout = ConfigSetting(type=NonNegativeInteger, value=30)
class ThorNodeConfig(ConfigSection):
__cfgfile__ = configuration_filename
__section__ = 'ThorNetwork'
enabled = False
domain = "sipthor.net"
multiply = 1000
certificate = ConfigSetting(type=Certificate, value=None)
private_key = ConfigSetting(type=PrivateKey, value=None)
ca = ConfigSetting(type=Certificate, value=None)
diff --git a/sylk/configuration/settings.py b/sylk/configuration/settings.py
index 4588905..2cd8e0c 100644
--- a/sylk/configuration/settings.py
+++ b/sylk/configuration/settings.py
@@ -1,121 +1,122 @@
# Copyright (C) 2010-2011 AG Projects. See LICENSE for details.
#
"""
SIP SIMPLE SDK settings extensions.
"""
__all__ = ['AccountExtension', 'BonjourAccountExtension', 'SylkServerSettingsExtension']
import os
from sipsimple.account import MSRPSettings as AccountMSRPSettings, NATTraversalSettings as AccountNATTraversalSettings
from sipsimple.account import RTPSettings as AccountRTPSettings, SIPSettings as AccountSIPSettings, TLSSettings as AccountTLSSettings
from sipsimple.configuration import CorrelatedSetting, Setting, SettingsObjectExtension
-from sipsimple.configuration.datatypes import MSRPTransport, NonNegativeInteger, Path, PortRange, SampleRate, SIPTransportList, SRTPEncryption
+from sipsimple.configuration.datatypes import MSRPConnectionModel, MSRPTransport, NonNegativeInteger, Path, PortRange, SampleRate, SIPTransportList, SRTPEncryption
from sipsimple.configuration.settings import AudioSettings, LogsSettings, RTPSettings, SIPSettings, TLSSettings
from sylk import __version__ as server_version
from sylk.configuration import ServerConfig, SIPConfig, MSRPConfig, RTPConfig
from sylk.configuration.datatypes import AudioCodecs, Port, SIPProxyAddress
# Account settings extensions
msrp_transport = 'tls' if MSRPConfig.use_tls else 'tcp'
class AccountMSRPSettingsExtension(AccountMSRPSettings):
transport = Setting(type=MSRPTransport, default=msrp_transport)
+ connection_model = Setting(type=MSRPConnectionModel, default='acm')
class AccountNATTraversalSettingsExtension(AccountNATTraversalSettings):
use_msrp_relay_for_inbound = Setting(type=bool, default=False)
use_msrp_relay_for_outbound = Setting(type=bool, default=False)
class AccountRTPSettingsExtension(AccountRTPSettings):
audio_codec_list = Setting(type=AudioCodecs, default=RTPConfig.audio_codecs, nillable=True)
srtp_encryption = Setting(type=SRTPEncryption, default=RTPConfig.srtp_encryption)
use_srtp_without_tls = Setting(type=bool, default=True)
class AccountSIPSettingsExtension(AccountSIPSettings):
register = Setting(type=bool, default=False)
outbound_proxy = Setting(type=SIPProxyAddress, default=SIPConfig.outbound_proxy, nillable=True)
tls_certificate = Path(ServerConfig.certificate) if ServerConfig.certificate and os.path.isfile(ServerConfig.certificate) else None
class AccountTLSSettingsExtension(AccountTLSSettings):
certificate = Setting(type=Path, default=tls_certificate, nillable=True)
verify_server = Setting(type=bool, default=ServerConfig.verify_server)
class AccountExtension(SettingsObjectExtension):
enabled = Setting(type=bool, default=True)
msrp = AccountMSRPSettingsExtension
nat_traversal = AccountNATTraversalSettingsExtension
rtp = AccountRTPSettingsExtension
sip = AccountSIPSettingsExtension
tls = AccountTLSSettingsExtension
class BonjourAccountExtension(SettingsObjectExtension):
enabled = Setting(type=bool, default=False)
# General settings extensions
class AudioSettingsExtension(AudioSettings):
input_device = Setting(type=str, default=None, nillable=True)
output_device = Setting(type=str, default=None, nillable=True)
sample_rate = Setting(type=SampleRate, default=16000)
log_directory = Path(ServerConfig.trace_dir) if ServerConfig.trace_dir else None
class LogsSettingsExtension(LogsSettings):
directory = Setting(type=Path, default=log_directory)
trace_sip = Setting(type=bool, default=ServerConfig.trace_sip)
trace_msrp = Setting(type=bool, default=ServerConfig.trace_msrp)
trace_pjsip = Setting(type=bool, default=False)
trace_notifications = Setting(type=bool, default=ServerConfig.trace_notifications)
class RTPSettingsExtension(RTPSettings):
port_range = Setting(type=PortRange, default=PortRange(RTPConfig.port_range.start, RTPConfig.port_range.end))
timeout = Setting(type=NonNegativeInteger, default=RTPConfig.timeout)
def sip_port_validator(port, sibling_port):
if port == sibling_port != 0:
raise ValueError("the TCP and TLS ports must be different")
transport_list = []
if SIPConfig.local_udp_port:
transport_list.append('udp')
if SIPConfig.local_tcp_port:
transport_list.append('tcp')
if SIPConfig.local_tls_port:
transport_list.append('tls')
udp_port = SIPConfig.local_udp_port or 0
tcp_port = SIPConfig.local_tcp_port or 0
tls_port = SIPConfig.local_tls_port or 0
class SIPSettingsExtension(SIPSettings):
udp_port = Setting(type=Port, default=udp_port)
tcp_port = CorrelatedSetting(type=Port, sibling='tls_port', validator=sip_port_validator, default=tcp_port)
tls_port = CorrelatedSetting(type=Port, sibling='tcp_port', validator=sip_port_validator, default=tls_port)
transport_list = Setting(type=SIPTransportList, default=transport_list)
ca_list = Path(ServerConfig.ca_file) if ServerConfig.ca_file and os.path.isfile(ServerConfig.ca_file) else None
class TLSSettingsExtension(TLSSettings):
ca_list = Setting(type=Path, default=ca_list, nillable=True)
class SylkServerSettingsExtension(SettingsObjectExtension):
user_agent = Setting(type=str, default='SylkServer-%s' % server_version)
audio = AudioSettingsExtension
logs = LogsSettingsExtension
rtp = RTPSettingsExtension
sip = SIPSettingsExtension
tls = TLSSettingsExtension
diff --git a/sylk/extensions.py b/sylk/extensions.py
index 6991ba7..bd28944 100644
--- a/sylk/extensions.py
+++ b/sylk/extensions.py
@@ -1,134 +1,81 @@
# Copyright (C) 2010-2011 AG Projects. See LICENSE for details.
#
import random
from datetime import datetime
-from application.notification import NotificationCenter
-from eventlet import api
-from msrplib.connect import get_acceptor, get_connector
from msrplib.protocol import URI
from msrplib.session import contains_mime_type
from sipsimple.account import AccountManager
from sipsimple.core import SDPAttribute
from sipsimple.payloads.iscomposing import IsComposingMessage, State, LastActive, Refresh, ContentType
from sipsimple.streams import MediaStreamRegistry
from sipsimple.streams.applications.chat import CPIMMessage
-from sipsimple.streams.msrp import ChatStream as _ChatStream, ChatStreamError, MSRPStreamBase, MSRPStreamError, NotificationProxyLogger
-from sipsimple.threading.green import run_in_green_thread
-from sipsimple.util import TimestampedNotificationData
-from twisted.python.failure import Failure
+from sipsimple.streams.msrp import ChatStream as _ChatStream, ChatStreamError, MSRPStreamBase
-from sylk.configuration import SIPConfig, MSRPConfig
+from sylk.configuration import SIPConfig
# We need to match on the only account that will be available
def _always_find_default_account(self, contact_uri):
return self.default_account
AccountManager.find_account = _always_find_default_account
# We need to be able to set the local identity in the message CPIM envelope
# so that messages appear to be coming from the users themselves, instead of
# just seeying the server identity
registry = MediaStreamRegistry()
for stream_type in registry.stream_types[:]:
if stream_type is _ChatStream:
registry.stream_types.remove(stream_type)
break
del registry
class ChatStream(_ChatStream):
accept_types = ['message/cpim']
accept_wrapped_types = ['*']
chatroom_capabilities = ['private-messages']
+ @property
+ def local_uri(self):
+ return URI(host=SIPConfig.local_ip, port=0, use_tls=self.transport=='tls', credentials=self.account.tls_credentials)
+
def _create_local_media(self, uri_path):
local_media = MSRPStreamBase._create_local_media(self, uri_path)
if self.session.local_focus and self.chatroom_capabilities:
local_media.attributes.append(SDPAttribute('chatroom', ' '.join(self.chatroom_capabilities)))
return local_media
def send_message(self, content, content_type='text/plain', local_identity=None, recipients=None, courtesy_recipients=None, subject=None, timestamp=None, required=None, additional_headers=None):
if self.direction=='recvonly':
raise ChatStreamError('Cannot send message on recvonly stream')
message_id = '%x' % random.getrandbits(64)
if not contains_mime_type(self.accept_wrapped_types, content_type):
raise ChatStreamError('Invalid content_type for outgoing message: %r' % content_type)
if not recipients:
recipients = [self.remote_identity]
if timestamp is None:
timestamp = datetime.now()
# Only use CPIM, it's the only type we accept
msg = CPIMMessage(content, content_type, sender=local_identity or self.local_identity, recipients=recipients, courtesy_recipients=courtesy_recipients,
subject=subject, timestamp=timestamp, required=required, additional_headers=additional_headers)
self._enqueue_message(message_id, str(msg), 'message/cpim', failure_report='yes', success_report='yes', notify_progress=True)
return message_id
def send_composing_indication(self, state, refresh, last_active=None, recipients=None, local_identity=None):
if self.direction == 'recvonly':
raise ChatStreamError('Cannot send message on recvonly stream')
if state not in ('active', 'idle'):
raise ValueError('Invalid value for composing indication state')
message_id = '%x' % random.getrandbits(64)
content = IsComposingMessage(state=State(state), refresh=Refresh(refresh), last_active=LastActive(last_active or datetime.now()), content_type=ContentType('text')).toxml()
if recipients is None:
recipients = [self.remote_identity]
# Only use CPIM, it's the only type we accept
msg = CPIMMessage(content, IsComposingMessage.content_type, sender=local_identity or self.local_identity, recipients=recipients, timestamp=datetime.now())
self._enqueue_message(message_id, str(msg), 'message/cpim', failure_report='partial', success_report='no')
return message_id
-# Patch MediaStreamBase initialize method
-# - There is no need for relay support
-# - We need to choose the outbound IP address
-@run_in_green_thread
-def _initialize(self, session, direction):
- self.greenlet = api.getcurrent()
- notification_center = NotificationCenter()
- notification_center.add_observer(self, sender=self)
- try:
- self.session = session
- outgoing = direction=='outgoing'
- self.transport = self.account.msrp.transport
- if not outgoing and self.transport == 'tls' and None in (self.account.tls_credentials.cert, self.account.tls_credentials.key):
- raise MSRPStreamError("Cannot accept MSRP connection without a TLS certificate")
- logger = NotificationProxyLogger()
- local_uri = URI(host=SIPConfig.local_ip,
- port=0,
- use_tls=self.transport=='tls',
- credentials=self.account.tls_credentials)
- if outgoing:
- if MSRPConfig.use_acm:
- # We start the transport as passive, because we expect the other end to become active. -Saul
- self.msrp_connector = get_acceptor(relay=None, use_acm=True, logger=logger)
- self.local_role = 'actpass'
- else:
- self.msrp_connector = get_connector(relay=None, use_acm=True, logger=logger)
- self.local_role = 'active'
- else:
- if self.remote_role in ('actpass', 'active'):
- self.msrp_connector = get_acceptor(relay=None, use_acm=True, logger=logger)
- self.local_role = 'passive'
- else:
- # Remote role is passive. Not allowed by the draft but play nice for interoperability. -Saul
- self.msrp_connector = get_connector(relay=None, use_acm=True, logger=logger)
- self.local_role = 'active'
- full_local_path = self.msrp_connector.prepare(local_uri)
- self.local_media = self._create_local_media(full_local_path)
- except api.GreenletExit:
- raise
- except Exception, ex:
- ndata = TimestampedNotificationData(context='initialize', failure=Failure(), reason=str(ex))
- notification_center.post_notification('MediaStreamDidFail', self, ndata)
- else:
- notification_center.post_notification('MediaStreamDidInitialize', self, data=TimestampedNotificationData())
- finally:
- if self.msrp_session is None and self.msrp is None and self.msrp_connector is None:
- notification_center.remove_observer(self, sender=self)
- self.greenlet = None
-
-MSRPStreamBase.initialize = _initialize
-
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Feb 1, 11:30 AM (1 d, 5 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3489299
Default Alt Text
(18 KB)
Attached To
Mode
rSYLK SylkServer
Attached
Detach File
Event Timeline
Log In to Comment