boat 0.2 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -17,4 +17,6 @@ Gem::Specification.new do |s|
17
17
  s.files = `git ls-files`.split("\n")
18
18
  s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
19
19
  s.require_path = 'lib'
20
+
21
+ s.add_dependency 'eventmachine'
20
22
  end
@@ -1,4 +1,4 @@
1
- require 'hmac/sha2'
1
+ require 'openssl'
2
2
  require 'socket'
3
3
 
4
4
  class Boat::Client
@@ -21,7 +21,7 @@ class Boat::Client
21
21
  raise Error, response unless response =~ /^251 HMAC-SHA256 (.+)/
22
22
 
23
23
  puts "[debug] sending password" if @debug
24
- password_hash = HMAC::SHA256.hexdigest(key, $1)
24
+ password_hash = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), key, $1)
25
25
  socket_puts "pass #{password_hash}"
26
26
  response = socket_gets.to_s
27
27
  raise Error, response unless response =~ /^250/
@@ -37,16 +37,17 @@ class Boat::Client
37
37
 
38
38
  size ||= io.respond_to?(:stat) ? io.stat.size : io.length
39
39
 
40
+ digest = OpenSSL::Digest.new('sha256')
40
41
  hash ||= if io.respond_to?(:path)
41
- Digest::SHA256.file(io.path)
42
+ digest.file(io.path).hexdigest
42
43
  elsif !io.respond_to?(:read)
43
- Digest::SHA256.hexdigest(io)
44
+ digest.hexdigest(io)
44
45
  else
45
46
  "-"
46
47
  end
47
48
 
48
- client_salt = [Digest::SHA256.digest((0..64).inject("") {|r, i| r << rand(256).chr})].pack("m").strip
49
- signature = HMAC::SHA256.hexdigest(@key, "#{server_salt}#{encoded_filename}#{size}#{hash}#{client_salt}")
49
+ client_salt = [digest.digest((0..64).inject("") {|r, i| r << rand(256).chr})].pack("m").strip
50
+ signature = OpenSSL::HMAC.hexdigest(digest, @key, "#{server_salt}#{encoded_filename}#{size}#{hash}#{client_salt}")
50
51
 
51
52
  puts "[debug] sending data command" if @debug
52
53
  socket_puts "data #{size} #{hash} #{client_salt} #{signature}"
@@ -54,7 +55,7 @@ class Boat::Client
54
55
 
55
56
  # The server might already have the file with this hash - if so it'll return 255 at this point.
56
57
  if matches = response.strip.match(/\A255 accepted ([0-9a-f]{64})\z/i)
57
- confirm_hash = HMAC::SHA256.hexdigest(@key, "#{client_salt}#{hash}")
58
+ confirm_hash = OpenSSL::HMAC.hexdigest(digest, @key, "#{client_salt}#{hash}")
58
59
  if matches[1] != confirm_hash
59
60
  raise Error, "Incorrect server signature; the srver may be faking that it received the upload"
60
61
  end
@@ -64,7 +65,7 @@ class Boat::Client
64
65
  raise Error, response unless response =~ /^253/
65
66
 
66
67
  if io.respond_to?(:read)
67
- digest = Digest::SHA256.new if hash == '-'
68
+ digest = OpenSSL::Digest.new('sha256') if hash == '-'
68
69
  written = 0
69
70
  while data = io.read(@chunk_size)
70
71
  if @debug
@@ -86,7 +87,7 @@ class Boat::Client
86
87
 
87
88
  if response =~ /^254/ # we need to send the hash of the file because we didn't on the DATA line
88
89
  hash = digest.to_s
89
- signature = HMAC::SHA256.hexdigest(@key, "#{server_salt}#{encoded_filename}#{size}#{hash}#{client_salt}")
90
+ signature = OpenSSL::HMAC.hexdigest(digest, @key, "#{server_salt}#{encoded_filename}#{size}#{hash}#{client_salt}")
90
91
 
91
92
  puts "[debug] sending confirm command" if @debug
92
93
  socket_puts "confirm #{hash} #{signature}\n"
@@ -95,7 +96,7 @@ class Boat::Client
95
96
 
96
97
  raise Error, response unless response && matches = response.strip.match(/\A255 accepted ([0-9a-f]{64})\z/i)
97
98
 
98
- confirm_hash = HMAC::SHA256.hexdigest(@key, "#{client_salt}#{hash}")
99
+ confirm_hash = OpenSSL::HMAC.hexdigest(digest, @key, "#{client_salt}#{hash}")
99
100
  if matches[1] != confirm_hash
100
101
  raise Error, "Incorrect server signature; the srver may be faking that it received the upload"
101
102
  end
@@ -1,7 +1,5 @@
1
- require 'hmac/sha2'
1
+ require 'openssl'
2
2
  require 'eventmachine'
3
- require 'syslog'
4
- require 'digest'
5
3
  require 'fileutils'
6
4
 
7
5
  class Boat::Server
@@ -22,6 +20,7 @@ class Boat::Server
22
20
  @@last_connection_id += 1
23
21
  @connection_id = @@last_connection_id
24
22
  @temporary_files = []
23
+ @digest = OpenSSL::Digest::Digest.new('sha256')
25
24
  send_data "220 Boat Server #{Boat::VERSION}\n"
26
25
  end
27
26
 
@@ -59,7 +58,7 @@ class Boat::Server
59
58
  send_data "500 USER first\n"
60
59
  else
61
60
  user = @configuration.fetch("users", {}).fetch(@username, nil)
62
- expected = HMAC::SHA256.hexdigest(user["key"], @login_salt) if user
61
+ expected = OpenSSL::HMAC.hexdigest(@digest, user["key"], @login_salt) if user
63
62
  if user && expected && args == expected
64
63
  send_data "250 OK\n"
65
64
  @user = user
@@ -107,10 +106,10 @@ class Boat::Server
107
106
 
108
107
  if size >= 1<<31
109
108
  send_data "500 size too large\n"
110
- elsif signature != HMAC::SHA256.hexdigest(@user["key"], "#{@put.fetch(:server_salt)}#{@put.fetch(:filename)}#{size}#{file_hash}#{client_salt}")
109
+ elsif signature != OpenSSL::HMAC.hexdigest(@digest, @user["key"], "#{@put.fetch(:server_salt)}#{@put.fetch(:filename)}#{size}#{file_hash}#{client_salt}")
111
110
  send_data "500 signature is invalid\n"
112
- elsif File.exists?(current_filename = "#{repository_path}/current.#{@put.fetch(:filename)}") && Digest::SHA256.file(current_filename).to_s == file_hash
113
- signature = HMAC::SHA256.hexdigest(@user["key"], "#{client_salt}#{file_hash}")
111
+ elsif File.exists?(current_filename = "#{repository_path}/current.#{@put.fetch(:filename)}") && OpenSSL::Digest.new('sha256').file(current_filename).to_s == file_hash
112
+ signature = OpenSSL::HMAC.hexdigest(@digest, @user["key"], "#{client_salt}#{file_hash}")
114
113
  send_data "255 accepted #{signature}\n"
115
114
  else
116
115
  @put[:temporary_id] = "#{Time.now.to_i}.#{Process.pid}.#{@connection_id}"
@@ -121,7 +120,7 @@ class Boat::Server
121
120
  :hash => (file_hash unless file_hash == '-'),
122
121
  :client_salt => client_salt,
123
122
  :file_handle => File.open(@put[:temporary_filename], "w"),
124
- :digest => Digest::SHA256.new)
123
+ :digest => OpenSSL::Digest.new('sha256'))
125
124
 
126
125
  @temporary_files << @put[:temporary_filename]
127
126
 
@@ -156,7 +155,7 @@ class Boat::Server
156
155
  file_hash = matches[1].downcase
157
156
  signature = matches[2].downcase
158
157
 
159
- if signature != HMAC::SHA256.hexdigest(@user["key"], "#{@put.fetch(:server_salt)}#{@put.fetch(:filename)}#{@put.fetch(:size)}#{file_hash}#{@put.fetch(:client_salt)}")
158
+ if signature != OpenSSL::HMAC.hexdigest(@digest, @user["key"], "#{@put.fetch(:server_salt)}#{@put.fetch(:filename)}#{@put.fetch(:size)}#{file_hash}#{@put.fetch(:client_salt)}")
160
159
  send_data "500 signature is invalid\n"
161
160
  @put = nil
162
161
  else
@@ -167,7 +166,7 @@ class Boat::Server
167
166
  end
168
167
 
169
168
  def complete_put
170
- calculated_hash = @put.fetch(:digest).to_s
169
+ calculated_hash = @put.fetch(:digest).hexdigest
171
170
 
172
171
  if @put.fetch(:hash) != calculated_hash
173
172
  send_data "500 file hash does not match hash supplied by client\n"
@@ -195,7 +194,7 @@ class Boat::Server
195
194
  end
196
195
  File.symlink(version_filename, symlink_name)
197
196
 
198
- signature = HMAC::SHA256.hexdigest(@user["key"], "#{@put.fetch(:client_salt)}#{@put.fetch(:hash)}")
197
+ signature = OpenSSL::HMAC.hexdigest(@digest, @user["key"], "#{@put.fetch(:client_salt)}#{@put.fetch(:hash)}")
199
198
  send_data "255 accepted #{signature}\n"
200
199
  ensure
201
200
  @put = nil
@@ -228,7 +227,7 @@ class Boat::Server
228
227
  end
229
228
 
230
229
  def random_salt
231
- [Digest::SHA256.digest((0..64).inject("") {|r, i| r << rand(256).chr})].pack("m").strip
230
+ [OpenSSL::Digest.new('sha256').digest((0..64).inject("") {|r, i| r << rand(256).chr})].pack("m").strip
232
231
  end
233
232
 
234
233
  def repository_path
@@ -277,8 +276,6 @@ class Boat::Server
277
276
  end
278
277
  end
279
278
 
280
- #Syslog.open 'boat'
281
-
282
279
  File.umask(0077)
283
280
  EventMachine.run do
284
281
  EventMachine.start_server(
@@ -1,3 +1,3 @@
1
1
  module Boat
2
- VERSION = "0.2"
2
+ VERSION = "0.2.1"
3
3
  end
@@ -1,7 +1,7 @@
1
1
  listen_address: localhost
2
2
  listen_port: 19184
3
3
 
4
- storage_path: /var/lib/boat
4
+ storage_path: /Users/roger/boat
5
5
 
6
6
  users:
7
7
  roger:
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: boat
3
3
  version: !ruby/object:Gem::Version
4
- hash: 15
4
+ hash: 21
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 2
9
- version: "0.2"
9
+ - 1
10
+ version: 0.2.1
10
11
  platform: ruby
11
12
  authors:
12
13
  - Roger Nesbitt
@@ -16,8 +17,21 @@ cert_chain: []
16
17
 
17
18
  date: 2011-05-30 00:00:00 +12:00
18
19
  default_executable:
19
- dependencies: []
20
-
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: eventmachine
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :runtime
34
+ version_requirements: *id001
21
35
  description: File upload client and server specifically aimed at transferring already-encrypted backups
22
36
  email: []
23
37