# encoding: UTF-8 module Vines class Stream class Server class AuthMethod < State VERIFY, VALID_TYPE, INVALID_TYPE = %w[verify valid invalid].map {|t| t.freeze } STARTTLS, RESULT, FROM, TO = %w[starttls result from to].map {|s| s.freeze } PROCEED = %Q{}.freeze FAILURE = %Q{}.freeze def initialize(stream, success=AuthRestart) super end def node(node) if dialback_verify?(node) id, from, to = %w[id from to].map {|a| node[a] } key = node.text outbound_stream = stream.router.stream_by_id(id) unless outbound_stream && outbound_stream.state.is_a?(Stream::Server::Outbound::AuthDialbackResult) stream.write(%Q{}) return end secret = outbound_stream.state.dialback_secret type = Kit.dialback_key(secret, from, to, id) == key ? VALID_TYPE : INVALID_TYPE stream.write(%Q{}) stream.close_connection_after_writing elsif starttls?(node) if stream.encrypt? stream.write(PROCEED) stream.encrypt stream.reset advance else stream.write(FAILURE) stream.write('') stream.close_connection_after_writing end elsif dialback_result?(node) # open a new connection and verify the dialback key stream.authoritative_dialback(node) else raise StreamErrors::NotAuthorized end end private def starttls?(node) node.name == STARTTLS && namespace(node) == NAMESPACES[:tls] end def dialback_verify?(node) node.name == VERIFY && namespace(node) == NAMESPACES[:legacy_dialback] end def dialback_result?(node) node.name == RESULT && namespace(node) == NAMESPACES[:legacy_dialback] end end end end end