25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

51 lines
1.5KB

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