You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

server.rb 1.9KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. require 'nokogiri'
  2. require 'resolv'
  3. module CryptCheck
  4. module Tls
  5. module Xmpp
  6. TLS_NAMESPACE = 'urn:ietf:params:xml:ns:xmpp-tls'
  7. RESOLVER = Resolv::DNS.new
  8. class Server < Tls::TcpServer
  9. attr_reader :domain
  10. def initialize(domain, type=:s2s, hostname: nil)
  11. @type, @domain = type, domain
  12. service, port = case type
  13. when :s2s then ['_xmpp-server', 5269]
  14. when :c2s then ['_xmpp-client', 5222]
  15. end
  16. unless hostname
  17. srv = RESOLVER.getresources("#{service}._tcp.#{domain}", Resolv::DNS::Resource::IN::SRV).sort_by(&:priority).first
  18. if srv
  19. hostname, port = srv.target.to_s, srv.port
  20. else # DNS is not correctly set, guess config…
  21. hostname = domain
  22. end
  23. end
  24. super hostname, port
  25. Logger.info { '' }
  26. Logger.info { self.required? ? 'Required'.colorize(:green) : 'Not required'.colorize(:yellow) }
  27. end
  28. def ssl_connect(socket, context, method, &block)
  29. type = case @type
  30. when :s2s then 'jabber:server'
  31. when :c2s then 'jabber:client'
  32. end
  33. socket.write "<?xml version='1.0' ?><stream:stream xmlns:stream='http://etherx.jabber.org/streams' xmlns='#{type}' to='#{@domain}' version='1.0'>"
  34. response = ''
  35. loop do
  36. response += socket.recv 1024
  37. xml = ::Nokogiri::XML response
  38. unless xml.xpath('//stream:features').empty?
  39. response = xml
  40. break
  41. end
  42. end
  43. starttls = response.xpath '//tls:starttls', tls: TLS_NAMESPACE
  44. raise TLSNotAvailableException unless starttls
  45. @required = !starttls.xpath('//tls:required', tls: TLS_NAMESPACE).nil?
  46. socket.write "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls' />\r\n"
  47. response = ::Nokogiri::XML socket.recv 4096
  48. raise TLSNotAvailableException unless response.xpath '//tls:proceed', tls: TLS_NAMESPACE
  49. super
  50. end
  51. def required?
  52. @required
  53. end
  54. end
  55. end
  56. end
  57. end