您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

63 行
1.8KB

  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. @type, @domain = type, domain
  14. service, port = case type
  15. when :s2s then ['_xmpp-server', 5269]
  16. when :c2s then ['_xmpp-client', 5222]
  17. end
  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. 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