SlideShare ist ein Scribd-Unternehmen logo
1 von 47
Downloaden Sie, um offline zu lesen
anchoring trust
r e w r i t i n g d n s f o r t h e
s e m a n t i c n e t w o r k w i t h
       r u b y a n d r a i l s


    http://slides.games-with-brains.net/
introduction
we are scientists




         romek szczesniak   eleanor mchugh
           cryptographer    physicist
romek@spikyblackcat.co.uk   eleanor@games-with-brains.com
we do science!
applied research

  semantic DNS infrastructure

  identity & access management

Rails-abuse, Ruby-fu, vapourware

  the wraith network packet sniffer

  the rindr DNS application server
the weasel words

danger! experimental code and concepts ahead

all such code is provided for entertainment
purposes only and should be used with
extreme caution, under adult supervision,
blah blah blah...

any resemblance to actual code & conceptsTM,
living or dead, is purely coincidental
the
semantic
network
today’s internet
packet switched network

based on Internet Protocol

each node has an IANA-allocated IP address

some IP addresses map to domain names

all domains ultimately map to IP addresses

nominally application agnostic
the dns system

defined in RFC 1034-1035 (November 1987)

resolves IP addresses from domain names

predominantly a static system

ISC BIND 9 is the base implementation

alternatives: NSD; MaraDNS; djbdns
a dns lookup
the following is the output of querying the
domain spikyblackcat.co.uk using dig
; <<>> DiG 9.3.4 <<>> spikyblackcat.co.uk
;; global options: printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 30042
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;spikyblackcat.co.uk. IN         A

;; ANSWER SECTION:
spikyblackcat.co.uk. 3600   IN       A   89.202.129.47

;; Query time: 276 msec
;; SERVER: 208.67.222.222#53(208.67.222.222)
;; WHEN: Mon Aug 20 19:38:13 2007
;; MSG SIZE rcvd: 53
semantic networking
 based on names rather than addresses

 exploits the dynamism in modern DNS

 not all domain names resolve to IP addresses

 embodies rich associations and content

 application and service oriented

 some parallels with semantic networks in AI
enum mapping
   telephone number

bridges the Internet and PSTN via DNS

service-oriented

RFCs 3401-3405 and RFC 3761

Conroy and Fujiwara’s ENUM experiences

Dynamic Delegation Discovery System

Naming Authority PoinTeRs
example enum domain
         01794833666                                6.6.6.3.3.8.4.9.7.1.4.4.e164.arpa
          6.6.6.3.3.8.4.9.7.1           is the phone number to connect to
          .4.4                          is the country dialing code for the UK
          .e164                         identifies the telephone numbering system
          .arpa                         is the internet infrastructure equivalent of .com




5   IN NAPTR     10   6   “U”     “E2U+web:http”        “!^.*$!http:maps.google.com/maps?output=png&q=SO51%2BUK&btnG=Search!”   .

5   IN NAPTR     10   6   “U”     “E2U+web:sip”                                  “!^.*$!sip:3666@roke.co.uk!”                   .

5   IN NAPTR     10   6   “U”   “E2U+x-skype:callto”                                  “!^.*$!callto:lconroy!”                   .

5   IN NAPTR     10   6   “U”     “E2U+voice:tel”                                   “!^.*$!tel:+441794833666!”                  .

5   IN NAPTR     10   6   “U”     “E2U+voice:tel”                                   “!^.*$!tel:+441794364902!”                  .

5   IN NAPTR     10   6   “U”     “E2U+voice:sip”                                “!^.*$!sip:3671@insensate.co.uk!”              .
the naptr resource
  naming authority pointer

specified in RFCs 2915 and 3403

allows URI rewriting using regular expressions

two modes of operation

 a terminal record replaces one URI with
 another when a regular expression is matched

 a non-terminal record redirects the DNS
 resolution to a specified domain name
the naptr resource
        naming authority pointer
           this table shows the two modes of NAPTR as
           they appear in a DNS zone record
TTL                   order preference   flag    service type            regex + replacement          terminator
600   IN      NAPTR   100       50       “u”     “E2U+sip”            “!^.*$!sip:joe@fish.com!”              .
600   IN      NAPTR   100       51       “”           “”                         “”                    test.com



      TTL                     time in seconds before record must be resolved from an authoritative server
      order                   order in which records should be evaluated
      preference              preference within a given order index
      flag                     “u” for a standard terminal record resource record as specified in the RFCs
      service type            ENUM to URI + service type for an ENUM-specific service type
      regex                   regular expression to use for matching
      replacement             string to replace the matched URI with
      terminator              either “.” or the target domain name for a non-terminal record
ruby naptr support
Telnic library

  developed in 2006

  open-source - available on enquiry

rindr library

  many lessons learnt from Telnic library

  supports enhanced NAPTR functionality
so what is rindr?
a Ruby DNS server

  UDP/TCP network server

  X(HT)ML and DNS protocols

  application-oriented NAPTR extensions

Rails integration via BackgrounDRb

will be published under an MIT license
rindr dns extensions

 DNS as a generic publishing infrastructure

 adds a relational data model to DNS

 backwards compatible for interoperability

 Identity and Access Management system

 Domain Markup Language
rails & the network

Rails uses HTTP(S)

Ruby has good support for other protocols

Rails is a single-threaded framework

network access blocks current thread

how about using a task server?
backgroundrb

task-server based on DRb

multi-threaded so non-blocking

MiddleMan objects acts as task proxy

Rails application polls task proxy
networking primer
feature-complete Ruby examples:

 UDP

 TCP

   TCPServer

   GServer

use BackgrouDRb for Rails integration
serving udp
require 'socket'                                                     def watchdog
require 'thread'                                                     end
require 'mutex_m'
                                                                    private
class UDPServer                                                      def spawn_watchdog
 include Mutex_m                                                      Thread.new {
 attr_reader :address, :port, :log, :timer                              STDOUT.puts quot;watchdog thread spawnedquot;
                                                                        loop do
 def initialize address, port                                             sleep 1
  @address, @port = address, port                                         @timer += 1
  @workers = []                                                           watchdog if @socket
  @timer = 0                                                            end
 end                                                                    }
                                                                     end
 def start
  @socket = UDPSocket.new                                            def event_loop options = {}
  @socket.bind(@address, @port)                                       @logging_enable = options[:logging]
  @socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1)     puts quot;server startedquot;
  spawn_watchdog
  event_loop :logging => true                                         loop do
 end                                                                   if sockets = select([@socket]) then
                                                                         sockets[0].each do |s|
 def stop                                                                 @workers << Thread.new(s) do |socket|
  @workers.each { |thread| thread.kill }                                   message, peer = *socket.recvfrom(512)
  lock                                                                     report(message)
   @socket.close                                                           reply, status = *serve(message)
   @socket = nil                                                           report(reply)
  unlock                                                                   UDPSocket.open.send(reply, status, peer[2], peer[1])
  puts quot;server stoppedquot;                                                   end
 end                                                                     end
                                                                         @workers.compact!
 def active?                                                           end
  @socket ? true : false                                              end
 end                                                                 end
                                                                    end
 def serve request
  [quot;helloquot;, 0]
 end
being a udp client
         generic client                                           sample server and client
require 'socket'                                         class ReverseServer < UDPServer                  class TimeClient < UDPClient
                                                          attr_reader :message_count                       def send
EndPoint = Struct.new(:host, :port)                                                                          message = quot;#{Time.now}quot;
                                                          def initialize address, port                       puts quot;sending message: #{message}quot;
class UDPClient                                            super                                             super message
 attr_reader :remote, :status                              @message_count = 0                                puts quot;received response #{receive()}quot;
                                                          end                                              end
 def initialize local_host, local_port                                                                    end
  @local = EndPoint.new(local_host, local_port)           def serve request
 end                                                       lock
                                                            @message_count += 1                           client = TimeClient.new(quot;localhostquot;, 3001)
 def connect remote_host, remote_port                      unlock                                         client.connect(quot;localhostquot;, 3000)
  raise if @socket                                         [request.reverse, 0]                           (1..300).each do |i|
  puts quot;starting clientquot;                                  end                                              client.send
  @remote = EndPoint.new(remote_host, remote_port)       end                                              end
  @socket = UDPSocket.open                                                                                client.disconnect
  @socket.bind(@local.host, @local.port)                 server = ReverseServer.new(quot;localhostquot;, 3000)
  @socket.send(quot;quot;, 0, @remote.host, @remote.port)        Thread.new do ||
 end                                                      server.start
                                                         end
 def send message
  @socket.send(message, 0, @remote.host, @remote.port)   while server.active?
 end                                                      while server.log.length > 0             starting client
                                                           puts server.log.shift                  sending message: Mon Sep 03 00:42:31 +0100 2007
 def receive max_bytes = 512                              end                                     received response 7002 0010+ 13:24:00 30 peS noM
  raise unless @socket                                    sleep 1                                 sending message: Mon Sep 03 00:42:31 +0100 2007
  message, @status = *(@socket.recvfrom(max_bytes))      end                                      received response 7002 0010+ 13:24:00 30 peS noM
  message                                                puts quot;server haltedquot;                     sending message: Mon Sep 03 00:42:31 +0100 2007
 end                                                                                              received response 7002 0010+ 13:24:00 30 peS noM
                                                                                                  sending message: Mon Sep 03 00:42:31 +0100 2007
 def disconnect                                                                                   received response 7002 0010+ 13:24:00 30 peS noM
  @socket.close                                                                                   sending message: Mon Sep 03 00:42:31 +0100 2007
  @socket = nil                                                                                   received response 7002 0010+ 13:24:00 30 peS noM
 end
end
gserver v. tcpserver

 GServer is convenient to use

   subclass and overload the serve method

   managed thread pool for easy multi-tasking

 TCPServer is flexible, allowing for more
 complex server designs
using tcpserver
require 'socket'                             private
require 'thread'                              def spawn_watchdog
require 'mutex_m'                              Thread.new {
                                                 loop do
class EnchancedTCPServer                           sleep 1
 include Mutex_m                                   @timer += 1
 attr_reader :address, :port, :log, :timer         on_watchdog if @server
                                                 end
 def initialize address, port                    }
  @address, @port = address, port             end
  @log = []
  @workers = []                               def event_loop options = {}
  @timer = 0                                   @logging_enable = options[:logging]
  @logging_enabled = false                     loop do
 end                                            on_connect(session = @server.accept)
                                                @workers << Thread.new(session) do |session|
 def start                                        loop do
  @server = TCPServer.new(@address, @port)         if session.eof? then
  spawn_watchdog                                     on_disconnect(session)
  event_loop :logging => true                        break
 end                                               else
                                                     on_serve(session)
 def stop                                          end
  @workers.each { |thread| thread.kill }          end
  lock                                            session.close
   @server = nil                                end
  unlock                                        @workers.compact!
  puts quot;server stoppedquot;                        end
 end                                          end

 def active?                                  def report message
  @server ? true : false                       if @logging_enabled then
 end                                             lock
                                                  @log << message.dup
 def on_connect session; end                     unlock
 def on_disconnect session; end                end
 def on_serve session; end                    end
 def on_watchdog; end                        end
being a tcp client
         generic client                                          sample server and client
require 'socket'                                        class ReverseServer < EnchancedTCPServer          class TimeClient < TCPClient
                                                         attr_reader :message_count, :max_count            def send
EndPoint = Struct.new(:host, :port)                                                                          message = quot;#{Time.now}quot;
                                                         def initialize address, port                        puts quot;sending message: #{message}quot;
class TCPClient                                           super                                              super message
 attr_reader :remote, :status                             @message_count = 0                               end
                                                         end
 def connect remote_host, remote_port                                                                      def on_response
  raise if @socket                                       def on_serve session                               line = receive
  puts quot;starting clientquot;                                  @message_count += 1                               puts quot;received response: #{line}quot;
  @remote = EndPoint.new(remote_host, remote_port)        message = (session.gets)[0..-2]                  end
  @socket = TCPSocket.new(@remote.host, @remote.port)     session.puts quot;reversing #{message}quot;             end
 end                                                      session.puts message.reverse
                                                         end
 def send message                                       end                                               client = TimeClient.new
  @socket.puts(message)                                                                                   client.connect(quot;localhostquot;, 3000)
  on_response                                           server = ReverseServer.new(quot;localhostquot;, 3000)     (1..2).each do |i|
 end                                                    Thread.new do ||                                   client.send
                                                         server.start                                      client.on_response
 def on_response; end                                   end                                                puts quot;==========quot;
                                                                                                           sleep 1
 def receive                                            while server.active?                              # client.receive
  raise unless @socket                                   while server.log.length > 0                      # sleep 1
  begin                                                   puts server.log.shift                           end
   response = @socket.gets                               end                                              client.disconnect
  end until response                                     sleep 1
  response                                              # puts quot;Timer count: #{server.timer} /
 end                                                    #{server.max_count}quot;                        starting client
                                                        end                                         sending message: Tue Sep 04 19:27:11 +0100 2007
 def disconnect                                         puts quot;server haltedquot;                        received response: reversing Tue Sep 04 19:27:11 +0100 2007
  @socket.close                                                                                     received response: 7002 0010+ 11:72:91 40 peS euT
  @socket = nil                                                                                     ==========
 end                                                                                                sending message: Tue Sep 04 19:27:12 +0100 2007
end                                                                                                 received response: reversing Tue Sep 04 19:27:12 +0100 2007
                                                                                                    received response: 7002 0010+ 21:72:91 40 peS euT
                                                                                                    ==========
the gserver way
         generic client                                      sample GServer and client
require 'socket'                                        require 'gserver'                                 class TimeClient < TCPClient
                                                                                                           def send
EndPoint = Struct.new(:host, :port)                     class ReverseServer < GServer                        message = quot;#{Time.now}quot;
                                                         def initialize host, port                           puts quot;sending message: #{message}quot;
class TCPClient                                            super port, host                                  super message
 attr_reader :remote, :status                            end                                               end

 def connect remote_host, remote_port                    def serve client                                  def on_response
  raise if @socket                                        puts quot;serving client: #{client.peeraddr[2]}quot;      line = receive
  puts quot;starting clientquot;                                  request = (client.gets)[0..-2]                    print quot;#{line.join(quot;quot;)}quot;
  @remote = EndPoint.new(remote_host, remote_port)        puts request                                     end
  @socket = TCPSocket.new(@remote.host, @remote.port)     client.puts(quot;request => #{request}quot;)            end
 end                                                      client.puts(quot;response => #{request.reverse}quot;)
                                                         end
 def send message                                       end                                               client = TimeClient.new
  @socket.puts(message)                                                                                   client.connect(quot;localhostquot;, 3000)
  on_response                                           server = ReverseServer.new(quot;localhostquot;, 3000)     (1..2).each do |i|
 end                                                    server.start                                       client.send
                                                        server.join                                        puts quot;==========quot;
 def on_response; end                                                                                      sleep 1
                                                                                                          end
 def receive                                                                                              client.disconnect
  raise unless @socket
  @socket.gets
 end

 def disconnect
  @socket.close                                                                                      starting client
  @socket = nil                                                                                      sending message: Tue Sep 04 22:17:27 +0100 2007
 end                                                                                                 request => Tue Sep 04 22:17:27 +0100 2007
end                                                                                                  response => 7002 0010+ 72:71:22 40 peS euT
                                                                                                     ==========
                                                                                                     starting client
                                                                                                     sending message: Tue Sep 04 22:17:29 +0100 2007
                                                                                                     request => Tue Sep 04 22:17:29 +0100 2007
                                                                                                     response => 7002 0010+ 92:71:22 40 peS euT
                                                                                                     ==========
anchoring
  trust
    in
   dns
ldap
lightwight directory access protocol

  International Telecommunications Union

  X.500 directory services over TCP/IP

  based on a tree of directory entries

  each directory entry is a set of attributes

  often used as an authentication repository

  Ruby/LDAP
single sign-on
distributed authentication infrastructure

  identity providers authenticate

  service providers serve client requests

various authentication schemes

  OpenID accepts a user-specified URI

  Kerberos issues a ticket on successful login
benefit of using dns

globally accessible

DNS as the anchor for online identity

individual and group Access Control Lists

prioritised contact mechanisms

supports software-oriented routing
dns insecurities

publicly viewable

globally accessible

lacks client authentication

server authentication via DNSSEC unwieldy
the .tel solution
ICANN authorised Top-Level Domain

uses domain names, i.e. romek.tel

globally accessible single point of contact

contact details stored as NAPTR records

provides a friending service for access control

proprietary DNS privacy model
example .tel entry
        romek.tel is provisioned with the following
        entries, with the .tel default TTL of 60 seconds
100      100    “u”       “E2U+sip”        “!^.*$!sip:3672@insensate.co.uk!”                    .
100      103    “u”   “E2U+email:mailto”   “!^.*$!mailto:romek@telnic.org!”                     .
100      110    “u”     “E2U+sms:tel”         “!^.*$!tel:+447833673805!”                        .
100      112    “u”    “E2U+web:http”       “!^.*$!http://www.telnic.org!”                      .
100      112    “u”    “E2U+web:https”      “!^.*$!https://www.telnic.org!”                     .
100      113    “u”      “E2U+ft:ftp”         “!^.*$!ftp://ftp.telnic.org!”                     .
100      114    “u”     “E2U+fax:tel”         “!^.*$!tel:+447833673805!”                        .
100      115    “u”     “E2U+sms:tel”         “!^.*$!tel:+447833673805!”                        .
100      116    “u”     “E2U+ems:tel”         “!^.*$!tel:+447833673805!”                        .
100      117    “u”     “E2U+mms:tel”         “!^.*$!tel:+447833673805!”                        .
100      118    “u”    “E2U+voice:tel”        “!^.*$!tel:+447833673805!”                        .
32767   32500   “”            “”                                               0.0.0.0.8.2.8.7.0.2.1.4.4.e164.arpa.
32767   32501   “”            “”                                                       lookup.telnic.org.
dns as data store
storage of application-specific data

pioneered by Project Athena’s Hesiod

  unordered TXT Resource Records

  publication of UNIX /etc/passwd file

NAPTR RRs ordered and structured

DNS as persistent relational data store
generic private data
non-proprietary private data in DNS

private data with access control

each user has a public/private key-pair

each record is encrypted with a session key

key-pairs are used to transmit the session key

no session key, no access!!!
naptr crypto recipe
     take a standard NAPTR record
IN   NAPTR 100     11   “u” “E2U+email:mailto”             “!^.*$!mailto:romeks@gmail.com!”             .




     encrypt with session key & initialisation vector
initialisation vector         +FgTpo7SPyd7cZx+cGVAtg==

     session key              /wVEQmHS4vhwO/AJTDqpGoXwMYYHiSUmZShY7GSCcrl=




     store results in an encrypted replacement field
IN   NAPTR 100     11   “u” “E2U+email:mailto” “!^.*$! HVnGeCBG4ISOvghq8jwylpFQmvotfaSjdgQ88ExkaIU=!”   .
a quick diagram
the downside of dns
globally accessible

  distributed key cracking

  private data cached anywhere

IETF standards evolve slowly

RR required for encrypted session key

trade-off between caching and update speed
ruby & cryptography
 supports the OpenSSL library

 Ruby Kaigi 2006 demonstration

 but still not ready for prime-time

   doesn’t address problems in OpenSSL

   no support for HSMs

   no pure Ruby crypto library
publicshamir adleman
                             key crypto
                      rivest
require 'openssl'                                     key = RSAKey.new
require 'base64'                                      key.create
                                                      puts quot;public key: #{key.public_key}quot;
class RSAKey                                          puts quot;private key: #{key.private_key}quot;
 PATTERNS = {
             :key => /^key: /
 }                      puts quot;plain text: #{text = 'something very secret'}quot;
                                                      puts quot;encrypted text: #{encrypted_text = Base64.encode64(key.encrypt(text))}quot;
 def initialize                                       puts quot;decrypted text: #{key.decrypt(Base64.decode64(encrypted_text))}quot;
  @key = nil
 end

 def create bits = 256
  @key = OpenSSL::PKey::RSA.new(bits) { print quot;.quot; }
  puts                                                public key:                -----BEGIN RSA PUBLIC KEY-----
 end                                                                             MCgCIQC6ovYcthdixInQTI9jQom5JkoYGHm
                                                                                 +kS6H8iXw01TZyQIDAQAB
 def public_key                                                                  -----END RSA PUBLIC KEY-----
  @key.public_key.to_pem                              private key:               -----BEGIN RSA PRIVATE KEY-----
 end                                                                             MIGrAgEAAiEAuqL2HLYXYsSJ0EyPY0KJuSZKGBh5vp
                                                                                 Euh/Il8NNU2ckCAwEAAQIh
 def private_key                                                                 ALhg1ZJ3sZK5ZwyJFf6RdUvrvcV1JfVpJJW/g/
  @key.to_pem                                                                    FT1YQBAhEA5gFML0nxGBgDr7ya
 end                                                                             AU+b8QIRAM+646/
                                                                                 S648QgsnCYXMg01kCEEzSCCEPQEA83RZYFtPzQ/
 def key= pem_data                                                               ECEBTUvPho
  @key = OpenSSL::PKey::RSA.new(pem_data)                                        wk56bWMmJveQlyECEQC6zIXUHHH04PwmQHERy08c
 end                                                                             -----END RSA PRIVATE KEY-----
                                                      plain text:                something very secret
 def encrypt text                                     encrypted text:            Z6mlEfMOVgyst3z9/ps9bF0ZD7myW9WPtjAKCAd7GFw=
  @key.public_encrypt(text)                           decrypted text:            something very secret
 end

 def decrypt text
  @key.private_decrypt(text)
 end
end
symmetric crypto
                    advanced encryption standard
require 'openssl'                                            private
require 'base64'                                              def run_cipher data
require 'digest/md5'                                           @cipher.key = @key
require 'digest/sha1'                                          @cipher.iv = @initialisation_vector
require 'digest/sha2'                                          cipher_text = @cipher.update(data)
                                                               (cipher_text << @cipher.final)
class AESDataStore                                            end
 attr_reader :key, :encrypted_text, :initialisation_vector   end

 def initialize key = nil, vector = nil                      text = quot;sample plain-textquot;
  @cipher = OpenSSL::Cipher::Cipher.new(quot;aes-256-cbcquot;)       encrypted_data_store = AESDataStore.new
  @encrypted_text = quot;quot;                                       encrypted_data_store.instance_eval do
  create_key(key, vector)                                     create_key
 end                                                          export_key
                                                              puts quot;original message: #{text}quot;
 def create_key key = nil, vector = nil                       puts quot;encrypted message: #{Base64.encode64(encrypt(text))}quot;
  @key = (key || OpenSSL::Random.random_bytes(256/8))         puts quot;decrypted message: #{decrypt()}quot;
  @initialisation_vector = (vector || @cipher.random_iv)      puts quot;key:         #{@key}quot;
 end                                                          puts quot;vector:       #{@initialisation_vector}quot;
                                                             end
 def encrypt data
  @cipher.encrypt
  @encrypted_text = run_cipher(data)
 end
                                                             original message:          sample plain-text
 def decrypt                                                 encrypted message:         qbPa75G+84M4+zc0ayiX4tttbtHPhhvooHRptMxDl6M=
  @cipher.decrypt                                            decrypted message:         sample plain-text
  run_cipher(@encrypted_text)                                key:                       ??? {??e??T??‫ݏ‬XM??6?‫ݏ‬Q??*@?z?
 end                                                         vector:                    ??? ??<I????P

 def export_key file_name = quot;aes-256-cbc.keyquot;
  key_file = File.new(file_name, quot;wquot;)
  key_file << quot;key: #{@key}nquot;
 end
a network key server
                                                          a simple server
require 'shared'                                                    private
require 'gserver'                                                    def authorise_action client, acl
                                                                      host = client.peeraddr[3]
class AESServer < GServer                                             key_name = client.get_line
 attr_reader :aes_keys, :acl, :server_key                             if acl[key_name].include?(host) then
                                                                        yield client, key_name if block_given?
 def initialize host, port                                            end
  super port, host                                                   end
  @server_key = RSAKey.new                                          end
  @aes_keys = {}
  @acl = {}                                                         server = AESServer.new(quot;localhostquot;, 3000)
 end                                                                server.instance_eval do
                                                                     create_key quot;1quot;
 def create_key key_name                                             create_key quot;2quot;
  @aes_keys[key_name] = AESDataStore.new                             create_key quot;3quot;
 end                                                                 authorise quot;::1quot;, quot;1quot;
                                                                     authorise quot;::1quot;, quot;2quot;
 def authorise host, key_name                                        start
  (@acl[key_name] ||= []) << host                                    join
 end                                                                end

 def serve client
  case client.get_line
  when quot;publicquot;
   client.puts @server_key.public_key.encode

  when quot;aesquot;
   authorise_action(client, @acl) do |client, key_name|
    raise unless @aes_keys[key_name]
    client_key = RSAKey.new(client.get_line.decode)
    aes_key = @aes_keys[key_name].key
    client.puts client_key.encrypt(aes_key).encode
   end
  end
 end
a network key server
                                           convenience functions
require 'socket'                                         class RSAKey
require 'openssl'                                         def initialize pem_data = nil
require 'base64'                                            @key = if pem_data then
                                                             OpenSSL::PKey::RSA.new(pem_data)
class IO                                                    else
 def get_line                                                OpenSSL::PKey::RSA.new(768))
   (line = gets) ? line.chop : line                         end
 end                                                      end
end
                                                          def public_key
class AESDataStore                                         @key.public_key.to_pem
 attr_reader :key, :encrypted_data                        end

 def initialize key = nil                                 def private_key
  @cipher = OpenSSL::Cipher::Cipher.new(quot;aes-256-cbcquot;)     @key.to_pem
  @encrypted_data = quot;quot;                                    end
  @key = (key || OpenSSL::Random.random_bytes(256/8))
 end                                                      def encrypt plain_data
                                                           @key.public_encrypt(plain_data) rescue quot;quot;
 def encrypt data                                         end
  @cipher.encrypt
  @encrypted_data = run_cipher(data)                      def decrypt plain_data
 end                                                       @key.private_decrypt(plain_data)
                                                          end
 def decrypt                                             end
  @cipher.decrypt
  run_cipher(@encrypted_data)                            class String
 end                                                      def decode
                                                            Base64.decode64(self)
private                                                   end
 def run_cipher data
  @cipher.key = @cipher.iv = @key                         def encode
  cipher_text = @cipher.update(data) + @cipher.final        Base64.encode64(self).tr(quot;=nquot;, quot;quot;)
 end                                                      end
end                                                      end
the rails middleman
                 the client rewritten with BackgrounDRb
class KeyServerWorker < BackgrounDRb::Worker::Base               private
 attr_reader :client_key                                          def connect
                                                                   raise if results[:socket]
 def do_work args                                                  begin
  @client_key ||= RSAKey.new                                         results[:socket] = TCPSocket.new(quot;localhostquot;, 3000)
  logger.info('requesting keys from server')                         value = yield(results[:socket]) if block_given?
  results[:request_time] = Time.now                                ensure
  results[:completed] = false                                        results[:socket].close
  load_server_key                                                    results[:socket] = nil
  args.each do |key_name|                                          end
   results[key_name] = get_aes_key(key_name)                       value
  end                                                             end
  results[:duration] = Time.now - results[:request_time]
  results[:completed] = true                                      def send message, *params
 end                                                               results[:socket].puts(message, *params)
                                                                  end
 def load_server_key
  @server_key = nil                                               def send_with_key message, *params
  connect do |server|                                              send message, *(params << @client_key.public_key.encode)
   send quot;publicquot;                                                  end
   results[:server_key] = RSAKey.new(@socket.get_line.decode))   end
  end                                                            KeyServerWorker.register
 end

 def get_aes_key key_name
  connect do |server|
   send_with_key quot;aesquot;, name
   results[:socket].get_line.decode rescue nil
  end
 end
bridging rails
        accessing the BackgrounDRb client from Rails
class KeyServerController < ApplicationController
 def start_background_task
   session[:job_key] = MiddleMan.new_worker(:class => :key_server_worker, :args => (1..3).to_a)
 end

 def keys
  if request.xhr?
    render :update do |page|
     page.call('list_keys', results[quot;1quot;], results[quot;2quot;], results[quot;3quot;])
     MiddleMan.delete_worker(session[:job_key]) if results[:completed]
    end
  else
    redirect_to :action => 'index'
  end
 end
end
conclusion
a new internet
the Internet is evolving

  dynamic, semantic name resolution

  Apache-style URI rewriting in DNS

  black-box data storage

AJAX-HTTP-DNS integration

attend our BoF in Salon 3 (19:30-20:30)

Weitere ähnliche Inhalte

Was ist angesagt?

Arp Dan Ipconfig Syntax
Arp Dan Ipconfig  SyntaxArp Dan Ipconfig  Syntax
Arp Dan Ipconfig Syntax
guestcc37e8c
 
The TCP/IP stack in the FreeBSD kernel COSCUP 2014
The TCP/IP stack in the FreeBSD kernel COSCUP 2014The TCP/IP stack in the FreeBSD kernel COSCUP 2014
The TCP/IP stack in the FreeBSD kernel COSCUP 2014
Kevin Lo
 
ikh331-06-distributed-programming
ikh331-06-distributed-programmingikh331-06-distributed-programming
ikh331-06-distributed-programming
Anung Ariwibowo
 
Programming TCP/IP with Sockets
Programming TCP/IP with SocketsProgramming TCP/IP with Sockets
Programming TCP/IP with Sockets
elliando dias
 

Was ist angesagt? (19)

How to make DSL
How to make DSLHow to make DSL
How to make DSL
 
DNS, DHCP Configuration
DNS, DHCP Configuration DNS, DHCP Configuration
DNS, DHCP Configuration
 
How to Avoid Common Mistakes When Using Reactor Netty
How to Avoid Common Mistakes When Using Reactor NettyHow to Avoid Common Mistakes When Using Reactor Netty
How to Avoid Common Mistakes When Using Reactor Netty
 
A22 Introduction to DTrace by Kyle Hailey
A22 Introduction to DTrace by Kyle HaileyA22 Introduction to DTrace by Kyle Hailey
A22 Introduction to DTrace by Kyle Hailey
 
Arp Dan Ipconfig Syntax
Arp Dan Ipconfig  SyntaxArp Dan Ipconfig  Syntax
Arp Dan Ipconfig Syntax
 
Warp 10 Platform Presentation - Criteo Beer & Tech 2016-02-03
Warp 10 Platform Presentation - Criteo Beer & Tech 2016-02-03Warp 10 Platform Presentation - Criteo Beer & Tech 2016-02-03
Warp 10 Platform Presentation - Criteo Beer & Tech 2016-02-03
 
Pf: the OpenBSD packet filter
Pf: the OpenBSD packet filterPf: the OpenBSD packet filter
Pf: the OpenBSD packet filter
 
The TCP/IP stack in the FreeBSD kernel COSCUP 2014
The TCP/IP stack in the FreeBSD kernel COSCUP 2014The TCP/IP stack in the FreeBSD kernel COSCUP 2014
The TCP/IP stack in the FreeBSD kernel COSCUP 2014
 
ikh331-06-distributed-programming
ikh331-06-distributed-programmingikh331-06-distributed-programming
ikh331-06-distributed-programming
 
Programming TCP/IP with Sockets
Programming TCP/IP with SocketsProgramming TCP/IP with Sockets
Programming TCP/IP with Sockets
 
Ns2programs
Ns2programsNs2programs
Ns2programs
 
Unix executable buffer overflow
Unix executable buffer overflowUnix executable buffer overflow
Unix executable buffer overflow
 
Staging driver sins
Staging driver sinsStaging driver sins
Staging driver sins
 
Scapy
ScapyScapy
Scapy
 
High Availability Server with DRBD in linux
High Availability Server with DRBD in linuxHigh Availability Server with DRBD in linux
High Availability Server with DRBD in linux
 
Mini CTF workshop dump
Mini CTF workshop dumpMini CTF workshop dump
Mini CTF workshop dump
 
Tracing Parallel Execution (UKOUG 2006)
Tracing Parallel Execution (UKOUG 2006)Tracing Parallel Execution (UKOUG 2006)
Tracing Parallel Execution (UKOUG 2006)
 
Vmlinux: anatomy of bzimage and how x86 64 processor is booted
Vmlinux: anatomy of bzimage and how x86 64 processor is bootedVmlinux: anatomy of bzimage and how x86 64 processor is booted
Vmlinux: anatomy of bzimage and how x86 64 processor is booted
 
Run Run Trema Test
Run Run Trema TestRun Run Trema Test
Run Run Trema Test
 

Andere mochten auch

Batalladepueblaygobiernodejurez 110505141701-phpapp01
Batalladepueblaygobiernodejurez 110505141701-phpapp01Batalladepueblaygobiernodejurez 110505141701-phpapp01
Batalladepueblaygobiernodejurez 110505141701-phpapp01
mariadelaluz1973
 
Unit 8 Moving ground
Unit 8 Moving groundUnit 8 Moving ground
Unit 8 Moving ground
E2 Consulting
 
Books of philippians and colossians [new testament] translated into the burmese
Books of philippians and colossians [new testament] translated into the burmeseBooks of philippians and colossians [new testament] translated into the burmese
Books of philippians and colossians [new testament] translated into the burmese
WorldBibles
 
Dr. Igor Calzada, Ph.D. Tesis Doctoral "¿Hacia una `Ciudad Vasca´? Aproximaci...
Dr. Igor Calzada, Ph.D. Tesis Doctoral "¿Hacia una `Ciudad Vasca´? Aproximaci...Dr. Igor Calzada, Ph.D. Tesis Doctoral "¿Hacia una `Ciudad Vasca´? Aproximaci...
Dr. Igor Calzada, Ph.D. Tesis Doctoral "¿Hacia una `Ciudad Vasca´? Aproximaci...
Dr Igor Calzada, MBA, FeRSA
 
Confianza en medio de la Crisis
Confianza en medio de la CrisisConfianza en medio de la Crisis
Confianza en medio de la Crisis
Beb0_01
 
Materiales Infantil
Materiales InfantilMateriales Infantil
Materiales Infantil
guest06c0ce
 

Andere mochten auch (20)

Top 5 de guitarras fender
Top 5 de guitarras fenderTop 5 de guitarras fender
Top 5 de guitarras fender
 
Research Report: Customer Services in Social Media Channels
Research Report: Customer Services in Social Media ChannelsResearch Report: Customer Services in Social Media Channels
Research Report: Customer Services in Social Media Channels
 
5 razones por las que se debe aprender un segundo idioma como un freelancer
5 razones por las que se debe aprender un segundo idioma como un freelancer5 razones por las que se debe aprender un segundo idioma como un freelancer
5 razones por las que se debe aprender un segundo idioma como un freelancer
 
Live Happy Right Side Up
Live Happy Right Side UpLive Happy Right Side Up
Live Happy Right Side Up
 
Necesidades Especiales para la educación de niños
Necesidades Especiales para la educación de niñosNecesidades Especiales para la educación de niños
Necesidades Especiales para la educación de niños
 
Prof. Dr. Ralf Kreutzer - Marketing as a Service
Prof. Dr. Ralf Kreutzer - Marketing as a Service Prof. Dr. Ralf Kreutzer - Marketing as a Service
Prof. Dr. Ralf Kreutzer - Marketing as a Service
 
Convocatoria feria xxii 2014
Convocatoria feria xxii 2014Convocatoria feria xxii 2014
Convocatoria feria xxii 2014
 
OpenData: El ejemplo de datos abiertos de Dirección de Aduanas Uruguay
OpenData: El ejemplo de datos abiertos de Dirección de Aduanas UruguayOpenData: El ejemplo de datos abiertos de Dirección de Aduanas Uruguay
OpenData: El ejemplo de datos abiertos de Dirección de Aduanas Uruguay
 
Master experiencial en dirección de marketing para las industrias creativas
Master experiencial en dirección de marketing para las industrias creativasMaster experiencial en dirección de marketing para las industrias creativas
Master experiencial en dirección de marketing para las industrias creativas
 
Batalladepueblaygobiernodejurez 110505141701-phpapp01
Batalladepueblaygobiernodejurez 110505141701-phpapp01Batalladepueblaygobiernodejurez 110505141701-phpapp01
Batalladepueblaygobiernodejurez 110505141701-phpapp01
 
Unit 8 Moving ground
Unit 8 Moving groundUnit 8 Moving ground
Unit 8 Moving ground
 
Books of philippians and colossians [new testament] translated into the burmese
Books of philippians and colossians [new testament] translated into the burmeseBooks of philippians and colossians [new testament] translated into the burmese
Books of philippians and colossians [new testament] translated into the burmese
 
Dr. Igor Calzada, Ph.D. Tesis Doctoral "¿Hacia una `Ciudad Vasca´? Aproximaci...
Dr. Igor Calzada, Ph.D. Tesis Doctoral "¿Hacia una `Ciudad Vasca´? Aproximaci...Dr. Igor Calzada, Ph.D. Tesis Doctoral "¿Hacia una `Ciudad Vasca´? Aproximaci...
Dr. Igor Calzada, Ph.D. Tesis Doctoral "¿Hacia una `Ciudad Vasca´? Aproximaci...
 
Испански за начинаещи за една чаша кафе
Испански за начинаещи за една чаша кафеИспански за начинаещи за една чаша кафе
Испански за начинаещи за една чаша кафе
 
Confianza en medio de la Crisis
Confianza en medio de la CrisisConfianza en medio de la Crisis
Confianza en medio de la Crisis
 
Materiales Infantil
Materiales InfantilMateriales Infantil
Materiales Infantil
 
Evaluacion de desempeño
Evaluacion de desempeñoEvaluacion de desempeño
Evaluacion de desempeño
 
EstimulacióN Temprana
EstimulacióN TempranaEstimulacióN Temprana
EstimulacióN Temprana
 
Curso Merchandising Modulo 6
Curso Merchandising Modulo 6Curso Merchandising Modulo 6
Curso Merchandising Modulo 6
 
Modelo unico cogp seminario taller total eagg 2015
Modelo unico cogp seminario taller total eagg 2015Modelo unico cogp seminario taller total eagg 2015
Modelo unico cogp seminario taller total eagg 2015
 

Ähnlich wie Anchoring Trust: Rewriting DNS for the Semantic Network with Ruby and Rails

Using Node.js to Build Great Streaming Services - HTML5 Dev Conf
Using Node.js to  Build Great  Streaming Services - HTML5 Dev ConfUsing Node.js to  Build Great  Streaming Services - HTML5 Dev Conf
Using Node.js to Build Great Streaming Services - HTML5 Dev Conf
Tom Croucher
 
Use perl creating web services with xml rpc
Use perl creating web services with xml rpcUse perl creating web services with xml rpc
Use perl creating web services with xml rpc
Johnny Pork
 
Performance tweaks and tools for Linux (Joe Damato)
Performance tweaks and tools for Linux (Joe Damato)Performance tweaks and tools for Linux (Joe Damato)
Performance tweaks and tools for Linux (Joe Damato)
Ontico
 

Ähnlich wie Anchoring Trust: Rewriting DNS for the Semantic Network with Ruby and Rails (20)

The Ruby Guide to *nix Plumbing: on the quest for efficiency with Ruby [M|K]RI
The Ruby Guide to *nix Plumbing: on the quest for efficiency with Ruby [M|K]RIThe Ruby Guide to *nix Plumbing: on the quest for efficiency with Ruby [M|K]RI
The Ruby Guide to *nix Plumbing: on the quest for efficiency with Ruby [M|K]RI
 
Using Node.js to Build Great Streaming Services - HTML5 Dev Conf
Using Node.js to  Build Great  Streaming Services - HTML5 Dev ConfUsing Node.js to  Build Great  Streaming Services - HTML5 Dev Conf
Using Node.js to Build Great Streaming Services - HTML5 Dev Conf
 
Servers with Event Machine - David Troy - RailsConf 2011
Servers with Event Machine - David Troy - RailsConf 2011Servers with Event Machine - David Troy - RailsConf 2011
Servers with Event Machine - David Troy - RailsConf 2011
 
Linux Networking Commands
Linux Networking CommandsLinux Networking Commands
Linux Networking Commands
 
Introduction to sockets tcp ip protocol.ppt
Introduction to sockets tcp ip protocol.pptIntroduction to sockets tcp ip protocol.ppt
Introduction to sockets tcp ip protocol.ppt
 
Basics of sockets
Basics of socketsBasics of sockets
Basics of sockets
 
Socket Programming
Socket ProgrammingSocket Programming
Socket Programming
 
Use perl creating web services with xml rpc
Use perl creating web services with xml rpcUse perl creating web services with xml rpc
Use perl creating web services with xml rpc
 
13048671.ppt
13048671.ppt13048671.ppt
13048671.ppt
 
Créer une base NoSQL en 1 heure
Créer une base NoSQL en 1 heureCréer une base NoSQL en 1 heure
Créer une base NoSQL en 1 heure
 
How to Leverage Go for Your Networking Needs
How to Leverage Go for Your Networking NeedsHow to Leverage Go for Your Networking Needs
How to Leverage Go for Your Networking Needs
 
Sockets in unix
Sockets in unixSockets in unix
Sockets in unix
 
Performance tweaks and tools for Linux (Joe Damato)
Performance tweaks and tools for Linux (Joe Damato)Performance tweaks and tools for Linux (Joe Damato)
Performance tweaks and tools for Linux (Joe Damato)
 
03 sockets
03 sockets03 sockets
03 sockets
 
Linux Networking Explained
Linux Networking ExplainedLinux Networking Explained
Linux Networking Explained
 
Basic socket programming
Basic socket programmingBasic socket programming
Basic socket programming
 
Ubuntu server wireless access point (eng)
Ubuntu server wireless access point (eng)Ubuntu server wireless access point (eng)
Ubuntu server wireless access point (eng)
 
Socket Programming
Socket ProgrammingSocket Programming
Socket Programming
 
Server side JavaScript: going all the way
Server side JavaScript: going all the wayServer side JavaScript: going all the way
Server side JavaScript: going all the way
 
[오픈소스컨설팅] Linux Network Troubleshooting
[오픈소스컨설팅] Linux Network Troubleshooting[오픈소스컨설팅] Linux Network Troubleshooting
[오픈소스컨설팅] Linux Network Troubleshooting
 

Mehr von Eleanor McHugh

Mehr von Eleanor McHugh (20)

[2023] Putting the R! in R&D.pdf
[2023] Putting the R! in R&D.pdf[2023] Putting the R! in R&D.pdf
[2023] Putting the R! in R&D.pdf
 
Generics, Reflection, and Efficient Collections
Generics, Reflection, and Efficient CollectionsGenerics, Reflection, and Efficient Collections
Generics, Reflection, and Efficient Collections
 
The Relevance of Liveness - Biometrics and Data Integrity
The Relevance of Liveness - Biometrics and Data IntegrityThe Relevance of Liveness - Biometrics and Data Integrity
The Relevance of Liveness - Biometrics and Data Integrity
 
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]The Browser Environment - A Systems Programmer's Perspective [sinatra edition]
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]
 
The Browser Environment - A Systems Programmer's Perspective
The Browser Environment - A Systems Programmer's PerspectiveThe Browser Environment - A Systems Programmer's Perspective
The Browser Environment - A Systems Programmer's Perspective
 
Go for the paranoid network programmer, 3rd edition
Go for the paranoid network programmer, 3rd editionGo for the paranoid network programmer, 3rd edition
Go for the paranoid network programmer, 3rd edition
 
An introduction to functional programming with Go [redux]
An introduction to functional programming with Go [redux]An introduction to functional programming with Go [redux]
An introduction to functional programming with Go [redux]
 
An introduction to functional programming with go
An introduction to functional programming with goAn introduction to functional programming with go
An introduction to functional programming with go
 
Implementing virtual machines in go & c 2018 redux
Implementing virtual machines in go & c 2018 reduxImplementing virtual machines in go & c 2018 redux
Implementing virtual machines in go & c 2018 redux
 
Identity & trust in Monitored Spaces
Identity & trust in Monitored SpacesIdentity & trust in Monitored Spaces
Identity & trust in Monitored Spaces
 
Don't Ask, Don't Tell - The Virtues of Privacy By Design
Don't Ask, Don't Tell - The Virtues of Privacy By DesignDon't Ask, Don't Tell - The Virtues of Privacy By Design
Don't Ask, Don't Tell - The Virtues of Privacy By Design
 
Don't ask, don't tell the virtues of privacy by design
Don't ask, don't tell   the virtues of privacy by designDon't ask, don't tell   the virtues of privacy by design
Don't ask, don't tell the virtues of privacy by design
 
Anonymity, identity, trust
Anonymity, identity, trustAnonymity, identity, trust
Anonymity, identity, trust
 
Going Loopy - Adventures in Iteration with Google Go
Going Loopy - Adventures in Iteration with Google GoGoing Loopy - Adventures in Iteration with Google Go
Going Loopy - Adventures in Iteration with Google Go
 
Distributed Ledgers: Anonymity & Immutability at Scale
Distributed Ledgers: Anonymity & Immutability at ScaleDistributed Ledgers: Anonymity & Immutability at Scale
Distributed Ledgers: Anonymity & Immutability at Scale
 
Hello Go
Hello GoHello Go
Hello Go
 
Go for the paranoid network programmer, 2nd edition
Go for the paranoid network programmer, 2nd editionGo for the paranoid network programmer, 2nd edition
Go for the paranoid network programmer, 2nd edition
 
Going Loopy: Adventures in Iteration with Go
Going Loopy: Adventures in Iteration with GoGoing Loopy: Adventures in Iteration with Go
Going Loopy: Adventures in Iteration with Go
 
Finding a useful outlet for my many Adventures in go
Finding a useful outlet for my many Adventures in goFinding a useful outlet for my many Adventures in go
Finding a useful outlet for my many Adventures in go
 
Anonymity, trust, accountability
Anonymity, trust, accountabilityAnonymity, trust, accountability
Anonymity, trust, accountability
 

Kürzlich hochgeladen

Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
Earley Information Science
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
giselly40
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
vu2urc
 

Kürzlich hochgeladen (20)

Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 

Anchoring Trust: Rewriting DNS for the Semantic Network with Ruby and Rails

  • 1. anchoring trust r e w r i t i n g d n s f o r t h e s e m a n t i c n e t w o r k w i t h r u b y a n d r a i l s http://slides.games-with-brains.net/
  • 3. we are scientists romek szczesniak eleanor mchugh cryptographer physicist romek@spikyblackcat.co.uk eleanor@games-with-brains.com
  • 4. we do science! applied research semantic DNS infrastructure identity & access management Rails-abuse, Ruby-fu, vapourware the wraith network packet sniffer the rindr DNS application server
  • 5. the weasel words danger! experimental code and concepts ahead all such code is provided for entertainment purposes only and should be used with extreme caution, under adult supervision, blah blah blah... any resemblance to actual code & conceptsTM, living or dead, is purely coincidental
  • 7. today’s internet packet switched network based on Internet Protocol each node has an IANA-allocated IP address some IP addresses map to domain names all domains ultimately map to IP addresses nominally application agnostic
  • 8. the dns system defined in RFC 1034-1035 (November 1987) resolves IP addresses from domain names predominantly a static system ISC BIND 9 is the base implementation alternatives: NSD; MaraDNS; djbdns
  • 9. a dns lookup the following is the output of querying the domain spikyblackcat.co.uk using dig ; <<>> DiG 9.3.4 <<>> spikyblackcat.co.uk ;; global options: printcmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 30042 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;spikyblackcat.co.uk. IN A ;; ANSWER SECTION: spikyblackcat.co.uk. 3600 IN A 89.202.129.47 ;; Query time: 276 msec ;; SERVER: 208.67.222.222#53(208.67.222.222) ;; WHEN: Mon Aug 20 19:38:13 2007 ;; MSG SIZE rcvd: 53
  • 10. semantic networking based on names rather than addresses exploits the dynamism in modern DNS not all domain names resolve to IP addresses embodies rich associations and content application and service oriented some parallels with semantic networks in AI
  • 11. enum mapping telephone number bridges the Internet and PSTN via DNS service-oriented RFCs 3401-3405 and RFC 3761 Conroy and Fujiwara’s ENUM experiences Dynamic Delegation Discovery System Naming Authority PoinTeRs
  • 12. example enum domain 01794833666 6.6.6.3.3.8.4.9.7.1.4.4.e164.arpa 6.6.6.3.3.8.4.9.7.1 is the phone number to connect to .4.4 is the country dialing code for the UK .e164 identifies the telephone numbering system .arpa is the internet infrastructure equivalent of .com 5 IN NAPTR 10 6 “U” “E2U+web:http” “!^.*$!http:maps.google.com/maps?output=png&q=SO51%2BUK&btnG=Search!” . 5 IN NAPTR 10 6 “U” “E2U+web:sip” “!^.*$!sip:3666@roke.co.uk!” . 5 IN NAPTR 10 6 “U” “E2U+x-skype:callto” “!^.*$!callto:lconroy!” . 5 IN NAPTR 10 6 “U” “E2U+voice:tel” “!^.*$!tel:+441794833666!” . 5 IN NAPTR 10 6 “U” “E2U+voice:tel” “!^.*$!tel:+441794364902!” . 5 IN NAPTR 10 6 “U” “E2U+voice:sip” “!^.*$!sip:3671@insensate.co.uk!” .
  • 13. the naptr resource naming authority pointer specified in RFCs 2915 and 3403 allows URI rewriting using regular expressions two modes of operation a terminal record replaces one URI with another when a regular expression is matched a non-terminal record redirects the DNS resolution to a specified domain name
  • 14. the naptr resource naming authority pointer this table shows the two modes of NAPTR as they appear in a DNS zone record TTL order preference flag service type regex + replacement terminator 600 IN NAPTR 100 50 “u” “E2U+sip” “!^.*$!sip:joe@fish.com!” . 600 IN NAPTR 100 51 “” “” “” test.com TTL time in seconds before record must be resolved from an authoritative server order order in which records should be evaluated preference preference within a given order index flag “u” for a standard terminal record resource record as specified in the RFCs service type ENUM to URI + service type for an ENUM-specific service type regex regular expression to use for matching replacement string to replace the matched URI with terminator either “.” or the target domain name for a non-terminal record
  • 15. ruby naptr support Telnic library developed in 2006 open-source - available on enquiry rindr library many lessons learnt from Telnic library supports enhanced NAPTR functionality
  • 16. so what is rindr? a Ruby DNS server UDP/TCP network server X(HT)ML and DNS protocols application-oriented NAPTR extensions Rails integration via BackgrounDRb will be published under an MIT license
  • 17. rindr dns extensions DNS as a generic publishing infrastructure adds a relational data model to DNS backwards compatible for interoperability Identity and Access Management system Domain Markup Language
  • 18. rails & the network Rails uses HTTP(S) Ruby has good support for other protocols Rails is a single-threaded framework network access blocks current thread how about using a task server?
  • 19. backgroundrb task-server based on DRb multi-threaded so non-blocking MiddleMan objects acts as task proxy Rails application polls task proxy
  • 20. networking primer feature-complete Ruby examples: UDP TCP TCPServer GServer use BackgrouDRb for Rails integration
  • 21. serving udp require 'socket' def watchdog require 'thread' end require 'mutex_m' private class UDPServer def spawn_watchdog include Mutex_m Thread.new { attr_reader :address, :port, :log, :timer STDOUT.puts quot;watchdog thread spawnedquot; loop do def initialize address, port sleep 1 @address, @port = address, port @timer += 1 @workers = [] watchdog if @socket @timer = 0 end end } end def start @socket = UDPSocket.new def event_loop options = {} @socket.bind(@address, @port) @logging_enable = options[:logging] @socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1) puts quot;server startedquot; spawn_watchdog event_loop :logging => true loop do end if sockets = select([@socket]) then sockets[0].each do |s| def stop @workers << Thread.new(s) do |socket| @workers.each { |thread| thread.kill } message, peer = *socket.recvfrom(512) lock report(message) @socket.close reply, status = *serve(message) @socket = nil report(reply) unlock UDPSocket.open.send(reply, status, peer[2], peer[1]) puts quot;server stoppedquot; end end end @workers.compact! def active? end @socket ? true : false end end end end def serve request [quot;helloquot;, 0] end
  • 22. being a udp client generic client sample server and client require 'socket' class ReverseServer < UDPServer class TimeClient < UDPClient attr_reader :message_count def send EndPoint = Struct.new(:host, :port) message = quot;#{Time.now}quot; def initialize address, port puts quot;sending message: #{message}quot; class UDPClient super super message attr_reader :remote, :status @message_count = 0 puts quot;received response #{receive()}quot; end end def initialize local_host, local_port end @local = EndPoint.new(local_host, local_port) def serve request end lock @message_count += 1 client = TimeClient.new(quot;localhostquot;, 3001) def connect remote_host, remote_port unlock client.connect(quot;localhostquot;, 3000) raise if @socket [request.reverse, 0] (1..300).each do |i| puts quot;starting clientquot; end client.send @remote = EndPoint.new(remote_host, remote_port) end end @socket = UDPSocket.open client.disconnect @socket.bind(@local.host, @local.port) server = ReverseServer.new(quot;localhostquot;, 3000) @socket.send(quot;quot;, 0, @remote.host, @remote.port) Thread.new do || end server.start end def send message @socket.send(message, 0, @remote.host, @remote.port) while server.active? end while server.log.length > 0 starting client puts server.log.shift sending message: Mon Sep 03 00:42:31 +0100 2007 def receive max_bytes = 512 end received response 7002 0010+ 13:24:00 30 peS noM raise unless @socket sleep 1 sending message: Mon Sep 03 00:42:31 +0100 2007 message, @status = *(@socket.recvfrom(max_bytes)) end received response 7002 0010+ 13:24:00 30 peS noM message puts quot;server haltedquot; sending message: Mon Sep 03 00:42:31 +0100 2007 end received response 7002 0010+ 13:24:00 30 peS noM sending message: Mon Sep 03 00:42:31 +0100 2007 def disconnect received response 7002 0010+ 13:24:00 30 peS noM @socket.close sending message: Mon Sep 03 00:42:31 +0100 2007 @socket = nil received response 7002 0010+ 13:24:00 30 peS noM end end
  • 23. gserver v. tcpserver GServer is convenient to use subclass and overload the serve method managed thread pool for easy multi-tasking TCPServer is flexible, allowing for more complex server designs
  • 24. using tcpserver require 'socket' private require 'thread' def spawn_watchdog require 'mutex_m' Thread.new { loop do class EnchancedTCPServer sleep 1 include Mutex_m @timer += 1 attr_reader :address, :port, :log, :timer on_watchdog if @server end def initialize address, port } @address, @port = address, port end @log = [] @workers = [] def event_loop options = {} @timer = 0 @logging_enable = options[:logging] @logging_enabled = false loop do end on_connect(session = @server.accept) @workers << Thread.new(session) do |session| def start loop do @server = TCPServer.new(@address, @port) if session.eof? then spawn_watchdog on_disconnect(session) event_loop :logging => true break end else on_serve(session) def stop end @workers.each { |thread| thread.kill } end lock session.close @server = nil end unlock @workers.compact! puts quot;server stoppedquot; end end end def active? def report message @server ? true : false if @logging_enabled then end lock @log << message.dup def on_connect session; end unlock def on_disconnect session; end end def on_serve session; end end def on_watchdog; end end
  • 25. being a tcp client generic client sample server and client require 'socket' class ReverseServer < EnchancedTCPServer class TimeClient < TCPClient attr_reader :message_count, :max_count def send EndPoint = Struct.new(:host, :port) message = quot;#{Time.now}quot; def initialize address, port puts quot;sending message: #{message}quot; class TCPClient super super message attr_reader :remote, :status @message_count = 0 end end def connect remote_host, remote_port def on_response raise if @socket def on_serve session line = receive puts quot;starting clientquot; @message_count += 1 puts quot;received response: #{line}quot; @remote = EndPoint.new(remote_host, remote_port) message = (session.gets)[0..-2] end @socket = TCPSocket.new(@remote.host, @remote.port) session.puts quot;reversing #{message}quot; end end session.puts message.reverse end def send message end client = TimeClient.new @socket.puts(message) client.connect(quot;localhostquot;, 3000) on_response server = ReverseServer.new(quot;localhostquot;, 3000) (1..2).each do |i| end Thread.new do || client.send server.start client.on_response def on_response; end end puts quot;==========quot; sleep 1 def receive while server.active? # client.receive raise unless @socket while server.log.length > 0 # sleep 1 begin puts server.log.shift end response = @socket.gets end client.disconnect end until response sleep 1 response # puts quot;Timer count: #{server.timer} / end #{server.max_count}quot; starting client end sending message: Tue Sep 04 19:27:11 +0100 2007 def disconnect puts quot;server haltedquot; received response: reversing Tue Sep 04 19:27:11 +0100 2007 @socket.close received response: 7002 0010+ 11:72:91 40 peS euT @socket = nil ========== end sending message: Tue Sep 04 19:27:12 +0100 2007 end received response: reversing Tue Sep 04 19:27:12 +0100 2007 received response: 7002 0010+ 21:72:91 40 peS euT ==========
  • 26. the gserver way generic client sample GServer and client require 'socket' require 'gserver' class TimeClient < TCPClient def send EndPoint = Struct.new(:host, :port) class ReverseServer < GServer message = quot;#{Time.now}quot; def initialize host, port puts quot;sending message: #{message}quot; class TCPClient super port, host super message attr_reader :remote, :status end end def connect remote_host, remote_port def serve client def on_response raise if @socket puts quot;serving client: #{client.peeraddr[2]}quot; line = receive puts quot;starting clientquot; request = (client.gets)[0..-2] print quot;#{line.join(quot;quot;)}quot; @remote = EndPoint.new(remote_host, remote_port) puts request end @socket = TCPSocket.new(@remote.host, @remote.port) client.puts(quot;request => #{request}quot;) end end client.puts(quot;response => #{request.reverse}quot;) end def send message end client = TimeClient.new @socket.puts(message) client.connect(quot;localhostquot;, 3000) on_response server = ReverseServer.new(quot;localhostquot;, 3000) (1..2).each do |i| end server.start client.send server.join puts quot;==========quot; def on_response; end sleep 1 end def receive client.disconnect raise unless @socket @socket.gets end def disconnect @socket.close starting client @socket = nil sending message: Tue Sep 04 22:17:27 +0100 2007 end request => Tue Sep 04 22:17:27 +0100 2007 end response => 7002 0010+ 72:71:22 40 peS euT ========== starting client sending message: Tue Sep 04 22:17:29 +0100 2007 request => Tue Sep 04 22:17:29 +0100 2007 response => 7002 0010+ 92:71:22 40 peS euT ==========
  • 28. ldap lightwight directory access protocol International Telecommunications Union X.500 directory services over TCP/IP based on a tree of directory entries each directory entry is a set of attributes often used as an authentication repository Ruby/LDAP
  • 29. single sign-on distributed authentication infrastructure identity providers authenticate service providers serve client requests various authentication schemes OpenID accepts a user-specified URI Kerberos issues a ticket on successful login
  • 30. benefit of using dns globally accessible DNS as the anchor for online identity individual and group Access Control Lists prioritised contact mechanisms supports software-oriented routing
  • 31. dns insecurities publicly viewable globally accessible lacks client authentication server authentication via DNSSEC unwieldy
  • 32. the .tel solution ICANN authorised Top-Level Domain uses domain names, i.e. romek.tel globally accessible single point of contact contact details stored as NAPTR records provides a friending service for access control proprietary DNS privacy model
  • 33. example .tel entry romek.tel is provisioned with the following entries, with the .tel default TTL of 60 seconds 100 100 “u” “E2U+sip” “!^.*$!sip:3672@insensate.co.uk!” . 100 103 “u” “E2U+email:mailto” “!^.*$!mailto:romek@telnic.org!” . 100 110 “u” “E2U+sms:tel” “!^.*$!tel:+447833673805!” . 100 112 “u” “E2U+web:http” “!^.*$!http://www.telnic.org!” . 100 112 “u” “E2U+web:https” “!^.*$!https://www.telnic.org!” . 100 113 “u” “E2U+ft:ftp” “!^.*$!ftp://ftp.telnic.org!” . 100 114 “u” “E2U+fax:tel” “!^.*$!tel:+447833673805!” . 100 115 “u” “E2U+sms:tel” “!^.*$!tel:+447833673805!” . 100 116 “u” “E2U+ems:tel” “!^.*$!tel:+447833673805!” . 100 117 “u” “E2U+mms:tel” “!^.*$!tel:+447833673805!” . 100 118 “u” “E2U+voice:tel” “!^.*$!tel:+447833673805!” . 32767 32500 “” “” 0.0.0.0.8.2.8.7.0.2.1.4.4.e164.arpa. 32767 32501 “” “” lookup.telnic.org.
  • 34. dns as data store storage of application-specific data pioneered by Project Athena’s Hesiod unordered TXT Resource Records publication of UNIX /etc/passwd file NAPTR RRs ordered and structured DNS as persistent relational data store
  • 35. generic private data non-proprietary private data in DNS private data with access control each user has a public/private key-pair each record is encrypted with a session key key-pairs are used to transmit the session key no session key, no access!!!
  • 36. naptr crypto recipe take a standard NAPTR record IN NAPTR 100 11 “u” “E2U+email:mailto” “!^.*$!mailto:romeks@gmail.com!” . encrypt with session key & initialisation vector initialisation vector +FgTpo7SPyd7cZx+cGVAtg== session key /wVEQmHS4vhwO/AJTDqpGoXwMYYHiSUmZShY7GSCcrl= store results in an encrypted replacement field IN NAPTR 100 11 “u” “E2U+email:mailto” “!^.*$! HVnGeCBG4ISOvghq8jwylpFQmvotfaSjdgQ88ExkaIU=!” .
  • 38. the downside of dns globally accessible distributed key cracking private data cached anywhere IETF standards evolve slowly RR required for encrypted session key trade-off between caching and update speed
  • 39. ruby & cryptography supports the OpenSSL library Ruby Kaigi 2006 demonstration but still not ready for prime-time doesn’t address problems in OpenSSL no support for HSMs no pure Ruby crypto library
  • 40. publicshamir adleman key crypto rivest require 'openssl' key = RSAKey.new require 'base64' key.create puts quot;public key: #{key.public_key}quot; class RSAKey puts quot;private key: #{key.private_key}quot; PATTERNS = { :key => /^key: / } puts quot;plain text: #{text = 'something very secret'}quot; puts quot;encrypted text: #{encrypted_text = Base64.encode64(key.encrypt(text))}quot; def initialize puts quot;decrypted text: #{key.decrypt(Base64.decode64(encrypted_text))}quot; @key = nil end def create bits = 256 @key = OpenSSL::PKey::RSA.new(bits) { print quot;.quot; } puts public key: -----BEGIN RSA PUBLIC KEY----- end MCgCIQC6ovYcthdixInQTI9jQom5JkoYGHm +kS6H8iXw01TZyQIDAQAB def public_key -----END RSA PUBLIC KEY----- @key.public_key.to_pem private key: -----BEGIN RSA PRIVATE KEY----- end MIGrAgEAAiEAuqL2HLYXYsSJ0EyPY0KJuSZKGBh5vp Euh/Il8NNU2ckCAwEAAQIh def private_key ALhg1ZJ3sZK5ZwyJFf6RdUvrvcV1JfVpJJW/g/ @key.to_pem FT1YQBAhEA5gFML0nxGBgDr7ya end AU+b8QIRAM+646/ S648QgsnCYXMg01kCEEzSCCEPQEA83RZYFtPzQ/ def key= pem_data ECEBTUvPho @key = OpenSSL::PKey::RSA.new(pem_data) wk56bWMmJveQlyECEQC6zIXUHHH04PwmQHERy08c end -----END RSA PRIVATE KEY----- plain text: something very secret def encrypt text encrypted text: Z6mlEfMOVgyst3z9/ps9bF0ZD7myW9WPtjAKCAd7GFw= @key.public_encrypt(text) decrypted text: something very secret end def decrypt text @key.private_decrypt(text) end end
  • 41. symmetric crypto advanced encryption standard require 'openssl' private require 'base64' def run_cipher data require 'digest/md5' @cipher.key = @key require 'digest/sha1' @cipher.iv = @initialisation_vector require 'digest/sha2' cipher_text = @cipher.update(data) (cipher_text << @cipher.final) class AESDataStore end attr_reader :key, :encrypted_text, :initialisation_vector end def initialize key = nil, vector = nil text = quot;sample plain-textquot; @cipher = OpenSSL::Cipher::Cipher.new(quot;aes-256-cbcquot;) encrypted_data_store = AESDataStore.new @encrypted_text = quot;quot; encrypted_data_store.instance_eval do create_key(key, vector) create_key end export_key puts quot;original message: #{text}quot; def create_key key = nil, vector = nil puts quot;encrypted message: #{Base64.encode64(encrypt(text))}quot; @key = (key || OpenSSL::Random.random_bytes(256/8)) puts quot;decrypted message: #{decrypt()}quot; @initialisation_vector = (vector || @cipher.random_iv) puts quot;key: #{@key}quot; end puts quot;vector: #{@initialisation_vector}quot; end def encrypt data @cipher.encrypt @encrypted_text = run_cipher(data) end original message: sample plain-text def decrypt encrypted message: qbPa75G+84M4+zc0ayiX4tttbtHPhhvooHRptMxDl6M= @cipher.decrypt decrypted message: sample plain-text run_cipher(@encrypted_text) key: ??? {??e??T??‫ݏ‬XM??6?‫ݏ‬Q??*@?z? end vector: ??? ??<I????P def export_key file_name = quot;aes-256-cbc.keyquot; key_file = File.new(file_name, quot;wquot;) key_file << quot;key: #{@key}nquot; end
  • 42. a network key server a simple server require 'shared' private require 'gserver' def authorise_action client, acl host = client.peeraddr[3] class AESServer < GServer key_name = client.get_line attr_reader :aes_keys, :acl, :server_key if acl[key_name].include?(host) then yield client, key_name if block_given? def initialize host, port end super port, host end @server_key = RSAKey.new end @aes_keys = {} @acl = {} server = AESServer.new(quot;localhostquot;, 3000) end server.instance_eval do create_key quot;1quot; def create_key key_name create_key quot;2quot; @aes_keys[key_name] = AESDataStore.new create_key quot;3quot; end authorise quot;::1quot;, quot;1quot; authorise quot;::1quot;, quot;2quot; def authorise host, key_name start (@acl[key_name] ||= []) << host join end end def serve client case client.get_line when quot;publicquot; client.puts @server_key.public_key.encode when quot;aesquot; authorise_action(client, @acl) do |client, key_name| raise unless @aes_keys[key_name] client_key = RSAKey.new(client.get_line.decode) aes_key = @aes_keys[key_name].key client.puts client_key.encrypt(aes_key).encode end end end
  • 43. a network key server convenience functions require 'socket' class RSAKey require 'openssl' def initialize pem_data = nil require 'base64' @key = if pem_data then OpenSSL::PKey::RSA.new(pem_data) class IO else def get_line OpenSSL::PKey::RSA.new(768)) (line = gets) ? line.chop : line end end end end def public_key class AESDataStore @key.public_key.to_pem attr_reader :key, :encrypted_data end def initialize key = nil def private_key @cipher = OpenSSL::Cipher::Cipher.new(quot;aes-256-cbcquot;) @key.to_pem @encrypted_data = quot;quot; end @key = (key || OpenSSL::Random.random_bytes(256/8)) end def encrypt plain_data @key.public_encrypt(plain_data) rescue quot;quot; def encrypt data end @cipher.encrypt @encrypted_data = run_cipher(data) def decrypt plain_data end @key.private_decrypt(plain_data) end def decrypt end @cipher.decrypt run_cipher(@encrypted_data) class String end def decode Base64.decode64(self) private end def run_cipher data @cipher.key = @cipher.iv = @key def encode cipher_text = @cipher.update(data) + @cipher.final Base64.encode64(self).tr(quot;=nquot;, quot;quot;) end end end end
  • 44. the rails middleman the client rewritten with BackgrounDRb class KeyServerWorker < BackgrounDRb::Worker::Base private attr_reader :client_key def connect raise if results[:socket] def do_work args begin @client_key ||= RSAKey.new results[:socket] = TCPSocket.new(quot;localhostquot;, 3000) logger.info('requesting keys from server') value = yield(results[:socket]) if block_given? results[:request_time] = Time.now ensure results[:completed] = false results[:socket].close load_server_key results[:socket] = nil args.each do |key_name| end results[key_name] = get_aes_key(key_name) value end end results[:duration] = Time.now - results[:request_time] results[:completed] = true def send message, *params end results[:socket].puts(message, *params) end def load_server_key @server_key = nil def send_with_key message, *params connect do |server| send message, *(params << @client_key.public_key.encode) send quot;publicquot; end results[:server_key] = RSAKey.new(@socket.get_line.decode)) end end KeyServerWorker.register end def get_aes_key key_name connect do |server| send_with_key quot;aesquot;, name results[:socket].get_line.decode rescue nil end end
  • 45. bridging rails accessing the BackgrounDRb client from Rails class KeyServerController < ApplicationController def start_background_task session[:job_key] = MiddleMan.new_worker(:class => :key_server_worker, :args => (1..3).to_a) end def keys if request.xhr? render :update do |page| page.call('list_keys', results[quot;1quot;], results[quot;2quot;], results[quot;3quot;]) MiddleMan.delete_worker(session[:job_key]) if results[:completed] end else redirect_to :action => 'index' end end end
  • 47. a new internet the Internet is evolving dynamic, semantic name resolution Apache-style URI rewriting in DNS black-box data storage AJAX-HTTP-DNS integration attend our BoF in Salon 3 (19:30-20:30)