Commit 8e66fde

mokha <mokha@cisco.com>
2019-03-09 18:33:22
extract method to upgrade to ssl server.
1 parent 67b8f26
lib/minbox/cli.rb
@@ -1,8 +1,9 @@
-require 'thor'
 require 'mail'
+require 'net/smtp'
+require 'openssl'
+require 'thor'
 
 require 'minbox'
-require 'minbox/secure_server'
 
 module Minbox
   module Cli
@@ -17,10 +18,8 @@ module Minbox
           subject 'test message'
           body "#{Time.now} This is a test message."
         end
-        require 'net/smtp'
-        smtp = Net::SMTP.new(host, port)
-        smtp.enable_starttls
-        smtp.start do |smtp|
+        Net::SMTP.start(host, port) do |smtp|
+          #smtp.enable_starttls
           smtp.send_message(mail.to_s, 'me+1@example.org', 'them+1@example.com')
           smtp.send_message(mail.to_s, 'me+2@example.org', 'them+2@example.com')
         end
@@ -35,17 +34,6 @@ module Minbox
         end
       end
 
-      method_option :output, type: :array, default: ['stdout']
-      desc 'secure_server <HOST> <PORT>', 'SMTP secure server'
-      def secure_server(host = 'localhost', port = '25')
-        # publisher = Publisher.from(options[:output])
-        SecureServer.new(port).listen do |socket|
-          puts "HELLLLLLLOOOOO"
-          read_line = socket.gets
-          puts read_line
-        end
-      end
-
       desc 'version', 'Display the current version'
       def version
         say Minbox::VERSION
lib/minbox/client.rb
@@ -28,6 +28,9 @@ module Minbox
           write '502 Invalid/unsupported command'
         end
       end
+    rescue Errno::ECONNRESET, Errno::EPIPE => error
+      logger.error(error)
+      close
     end
 
     private
@@ -35,7 +38,6 @@ module Minbox
     def quit
       write "221 Bye"
       close
-      @server.downgrade
     end
 
     def data(line, &block)
@@ -47,7 +49,7 @@ module Minbox
         line = read
       end
       write "250 OK"
-      block.call(Mail.new(body.join))
+      block.call(Mail.new(body.join)) unless body.empty?
     end
 
     def rcpt_to(line)
@@ -63,7 +65,7 @@ module Minbox
       write "250-#{host}"
       #write "250 AUTH PLAIN LOGIN"
       write "250-ENHANCEDSTATUSCODES"
-      write "250 STARTTLS"
+      #write "250 STARTTLS"
       write "250 OK"
     end
 
@@ -74,15 +76,6 @@ module Minbox
 
     def start_tls
       write "220 Ready to start TLS"
-      ssl_context = OpenSSL::SSL::SSLContext.new()
-      ssl_context.cert = OpenSSL::X509::Certificate.new(File.open("server.pem"))
-      ssl_context.key = OpenSSL::PKey::RSA.new(File.open("server.pem"))
-      ssl_context.ssl_version = :SSLv23
-      ssl_socket = OpenSSL::SSL::SSLSocket.new(@socket, ssl_context)
-      # ssl_socket.sync_close = true
-      # ssl_socket.connect
-      @socket = ssl_socket
-      # write "502 TLS not available"
     end
 
     def reset
lib/minbox/secure_server.rb
@@ -1,18 +0,0 @@
-module Minbox
-  class SecureServer
-    
-    def initialize(port)
-      server = TCPServer.new(port)
-      sslContext = OpenSSL::SSL::SSLContext.new
-      sslContext.cert = OpenSSL::X509::Certificate.new(File.open("server.pem"))
-      sslContext.key = OpenSSL::PKey::RSA.new(File.open("server.pem"))
-      @sslServer = OpenSSL::SSL::SSLServer.new(server, sslContext)
-    end
-
-    def listen
-      loop do 
-        yield @sslServer.accept
-      end
-    end
-  end
-end
lib/minbox/server.rb
@@ -10,7 +10,8 @@ module Minbox
 
     def listen!(&block)
       logger.debug("Starting server on port #{port}...")
-      @server = @original_server = TCPServer.new(port.to_i)
+      @server = TCPServer.new(port.to_i)
+      #@server = upgrade(@server)
       logger.debug("Server started!")
 
       loop do
@@ -28,5 +29,50 @@ module Minbox
     def shutdown!
       @server&.close
     end
+
+    private
+
+    def upgrade(tcp_server)
+      server = OpenSSL::SSL::SSLServer.new(tcp_server, ssl_context)
+      server.start_immediately = true
+      server
+    end
+
+    def certificate_for(private_key)
+      certificate = OpenSSL::X509::Certificate.new
+      subject = '/C=CA/ST=AB/L=Calgary/O=minbox/OU=development/CN=minbox'
+      certificate.subject = certificate.issuer = OpenSSL::X509::Name.parse(subject)
+      certificate.not_before = Time.now
+      certificate.not_after = certificate.not_before + 30 * 24 * 60 * 60 # 30 days
+      certificate.public_key = private_key.public_key
+      certificate.serial = 1
+      certificate.version = 2
+      apply_ski_extension_to(certificate)
+      certificate.sign(private_key, OpenSSL::Digest::SHA256.new)
+      certificate
+    end
+
+    def apply_ski_extension_to(certificate)
+      extensions = OpenSSL::X509::ExtensionFactory.new
+      extensions.subject_certificate = certificate
+      extensions.issuer_certificate = certificate
+      certificate.add_extension(
+        extensions.create_extension('subjectKeyIdentifier', 'hash', false)
+      )
+      certificate.add_extension(
+        extensions.create_extension('keyUsage', 'keyEncipherment,digitalSignature', true)
+      )
+    end
+
+    def ssl_context(key = OpenSSL::PKey::RSA.new(2048))
+      ssl_context = OpenSSL::SSL::SSLContext.new
+      ssl_context.cert = certificate_for(key)
+      ssl_context.key = key
+      ssl_context.ssl_version = :SSLv23
+      ssl_context.renegotiation_cb = lambda do |ssl|
+        puts "Negotiating..."
+      end
+      ssl_context
+    end
   end
 end