arver 0.1.8 → 0.1.9

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b11992d186276bbaa51cef0eb4b05f51cc74ee1e0668dffb7f81122d8674e764
4
- data.tar.gz: 686b2e04289e64f90ac0064d2464ee3d5e7b6b29507cced0b51343b59033b9b7
3
+ metadata.gz: eeb29f1cdc8ba4b8fd5a05791fe282f1a016440253f0b3591c95e30f573343f5
4
+ data.tar.gz: d41505b368abe1d3aa20c3fdf0ed13c3e382aadeb18e9b000778f156279dce0d
5
5
  SHA512:
6
- metadata.gz: 8e8b53c4598c0ee397aa3fb47fabf697c906386fa1c0d6f6eacd01dec2fa118c4edff2c2fe68b97068aaf0f71e8975b42604730c1866e4e03a8668732c170478
7
- data.tar.gz: b499b9154521c7d98f327487b964d77022ac98e278ba43139b14526d09bf3f48c757691b03c2a53d43fb2624ecd90aae25c9794be0e505402f1c7e598ef401f7
6
+ metadata.gz: f63236b680841a83333b3fce1c6a6c379e0a35820554f016821f1aff3998011c844655a883cd5f0514481b20618490aec95d005f320cfa57472b9f95585c73ff
7
+ data.tar.gz: 5734e53e093a97465751ae5e9cd95cee18f9565337ea94208f7eea9448c7a32f79b53aa1f92a8e82f0ac4a88127ca13fd91ca6e9838f5b7aaa284a4b05ea8e91
data/CHANGELOG.textile CHANGED
@@ -1,3 +1,7 @@
1
+ === 0.1.9 2022-01-29
2
+
3
+ * Add a new --open-systemd to support opening disks at startup. This mode is compatible with systemd-ask-password which is used to open disks in the initrd.
4
+
1
5
  === 0.1.7 2018-09-01
2
6
 
3
7
  * Updated gems to work with 2.5.1
data/lib/arver/cli.rb CHANGED
@@ -59,6 +59,8 @@ module Arver
59
59
  opts.separator "Actions:"
60
60
  opts.on_tail( "-o TARGET", "--open TARGET", String,
61
61
  "Open target." ) { |arg| options[:argument][:target] = arg; options[:action] = :open; }
62
+ opts.on_tail( "--systemd-open TARGET", String,
63
+ "Open target during boot via systemd-asskpasswd." ) { |arg| options[:argument][:target] = arg; options[:action] = :systemd_open; }
62
64
  opts.on_tail( "-c TARGET", "--close TARGET", String,
63
65
  "Close target." ) { |arg| options[:argument][:target] = arg; options[:action] = :close; }
64
66
  opts.on_tail( "--create TARGET", String,
@@ -118,6 +120,7 @@ module Arver
118
120
  :gc => Arver::GCAction,
119
121
  :create => Arver::CreateAction,
120
122
  :open => Arver::OpenAction,
123
+ :systemd_open => Arver::SystemdOpenAction,
121
124
  :close => Arver::CloseAction,
122
125
  :adduser => Arver::AdduserAction,
123
126
  :deluser => Arver::DeluserAction,
@@ -1,8 +1,7 @@
1
1
  module Arver
2
2
  class CommandWrapper
3
-
4
3
  attr_accessor :command, :arguments_array, :return_value, :output
5
-
4
+
6
5
  def self.create( cmd, args = [] )
7
6
  c = CommandWrapper.new
8
7
  c.command= cmd
@@ -10,8 +9,12 @@ module Arver
10
9
  c
11
10
  end
12
11
 
13
- # copy from shellwords.rb
14
12
  def shellescape(str)
13
+ CommandWrapper.shellescape(str)
14
+ end
15
+
16
+ # copy from shellwords.rb
17
+ def self.shellescape(str)
15
18
  str = str.to_s
16
19
 
17
20
  # An empty argument will be skipped, so return empty quotes.
data/lib/arver/host.rb CHANGED
@@ -2,7 +2,7 @@ module Arver
2
2
  class Host
3
3
 
4
4
  attr_accessor :port, :username
5
- attr_writer :address
5
+ attr_writer :address, :boot_address
6
6
 
7
7
  include Arver::PartitionHierarchyNode
8
8
  include Arver::NodeWithScriptHooks
@@ -25,6 +25,11 @@ module Arver
25
25
  self.name
26
26
  end
27
27
 
28
+ def boot_address
29
+ return @boot_address unless @boot_address.nil?
30
+ address
31
+ end
32
+
28
33
  def port
29
34
  return @port unless @port.nil?
30
35
  '22'
@@ -44,6 +49,7 @@ module Arver
44
49
  def to_yaml
45
50
  yaml = ""
46
51
  yaml += "'address': '"+@address+"'\n" unless @address.nil?
52
+ yaml += "'boot_address': '"+@boot_address+"'\n" unless @boot_address.nil?
47
53
  yaml += "'port': '"+@port+"'\n" unless @port.nil?
48
54
  yaml += "'username': '"+@username+"'\n" unless @username.nil?
49
55
  yaml += script_hooks_to_yaml
@@ -61,6 +67,10 @@ module Arver
61
67
  self.address = data
62
68
  next
63
69
  end
70
+ if( name == "boot_address" )
71
+ self.boot_address = data
72
+ next
73
+ end
64
74
  if( name == "username" )
65
75
  self.username= data
66
76
  next
@@ -1,20 +1,29 @@
1
1
  module Arver
2
2
  class SSHCommandWrapper < CommandWrapper
3
-
4
- attr_accessor :host, :user, :port, :as_root
5
-
6
- def self.create( cmd, args, host, as_root = false )
3
+ attr_accessor :host, :user, :port, :as_root, :on_boot
4
+
5
+ def self.create( cmd, args, host, as_root = false, on_boot = false)
7
6
  c = SSHCommandWrapper.new
8
7
  c.host= host
9
8
  c.as_root= as_root
10
9
  c.command= cmd
11
10
  c.arguments_array= args
11
+ c.on_boot = on_boot
12
12
  c
13
13
  end
14
-
14
+
15
15
  def escaped_command
16
- sudo = if as_root && host.username != "root" then "sudo" else "" end
17
- "ssh -p #{shellescape(host.port)} #{shellescape(host.username)}@#{shellescape(host.address)} #{sudo} #{super}"
16
+ addr = (on_boot ? host.boot_address : nil) || host.address
17
+ user = on_boot ? 'root' : host.username
18
+ port = on_boot ? '22' : host.port
19
+ sudo = if as_root && on_boot && host.username != "root" then "sudo" else "" end
20
+ "ssh -p #{shellescape(port)} #{shellescape(user)}@#{shellescape(addr)} #{sudo} #{super}"
21
+ end
22
+
23
+ def self.is_system_running?(partition)
24
+ wr = Arver::SSHCommandWrapper.create("systemctl", ["is-system-running"], partition.parent, true, true)
25
+ wr.execute
26
+ wr.success? && !['initializing','starting'].include?(wr.output.chomp)
18
27
  end
19
28
  end
20
29
  end
@@ -0,0 +1,83 @@
1
+ require 'tmpdir'
2
+
3
+ module Arver
4
+ class SystemdOpenAction < Action
5
+ def initialize( target_list )
6
+ super( target_list )
7
+ self.open_keystore
8
+ end
9
+
10
+ def verify?( partition )
11
+ if(Arver::SSHCommandWrapper.is_system_running?(partition))
12
+ Arver::Log.error( "#{partition.parent.name} already up. Use normal open, skipping." )
13
+ return false
14
+ end
15
+ return false unless load_key( partition )
16
+ true
17
+ end
18
+
19
+ def get_socket(host, partid)
20
+ # Check which partitions are waiting for a password
21
+ # see https://www.freedesktop.org/wiki/Software/systemd/PasswordAgents/
22
+ files_exec = Arver::SSHCommandWrapper.create("ls", ["/run/systemd/ask-password/ask.*"], host, true, true)
23
+ files_exec.execute
24
+ files = files_exec.output.split("\n")
25
+
26
+ # Find the socket for the partition we want to open
27
+ files.each do |f|
28
+ f_exec = Arver::SSHCommandWrapper.create("cat", [f], host, true, true)
29
+ f_exec.execute
30
+ ask_file = f_exec.output
31
+ if ask_file =~ /#{partid}/
32
+ ask_file =~ /Socket=(.*)/
33
+ return $1
34
+ end
35
+ end
36
+ nil
37
+ end
38
+
39
+ def execute_partition( partition )
40
+ Arver::Log.info( "opening: "+partition.path )
41
+ socket = nil
42
+ partid = nil
43
+ host = partition.parent
44
+
45
+ # Find the uuid of this partition
46
+ partid_exec = Arver::SSHCommandWrapper.create("blkid", ["/dev/#{partition.device}"], host, true, true)
47
+ partid_exec.execute
48
+ partid = partid_exec.output.chomp.gsub(/.* UUID=\"([^"]+)\" .*/,'\1')
49
+ unless partid =~ /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/
50
+ puts "Could not get uuid of disk"
51
+ throw( :abort_action )
52
+ end
53
+
54
+ socket = get_socket(host, partid)
55
+ if socket.nil?
56
+ puts "Disk is not waiting to be opened"
57
+ throw( :abort_action )
58
+ end
59
+
60
+ # Upload password-agent binary and supply password to the correct socket
61
+ binary = File.join(ROOT_DIR, "vendor", "password-agent")
62
+ unless File.exists?(binary)
63
+ puts "This gem is missing the native password-agent binary"
64
+ throw( :abort_action )
65
+ end
66
+ # This is an epic hack to have a binary with exec permission
67
+ # initrd does not have chmod, so we copy an existing binary and override it
68
+ r = Arver::SSHCommandWrapper.create("cp", ["/bin/true", "/run/password-agent"], host, true, true).execute
69
+ r = Arver::SSHCommandWrapper.create("cat", ["- > /run/password-agent"], host, true, true)
70
+ r.execute(File.read(binary))
71
+ unless r.success?
72
+ puts "Could not upload password-agent"
73
+ throw( :abort_action )
74
+ end
75
+
76
+ # Pass password
77
+ a = Arver::SSHCommandWrapper.create("/run/password-agent", [socket], host, true, true)
78
+ a.execute(key)
79
+
80
+ # Cannot check if it worked, since if it did, the server rebooted
81
+ end
82
+ end
83
+ end
data/lib/arver/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Arver
2
- VERSION = '0.1.8'
2
+ VERSION = '0.1.9'
3
3
  end
data/lib/arver.rb CHANGED
@@ -2,5 +2,6 @@
2
2
  $:.unshift(File.dirname(__FILE__)) unless
3
3
  $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
4
4
 
5
- %w{ gpg_key_manager luks_wrapper action initial_config_action refresh_action create_action list_action gc_action adduser_action deluser_action info_action close_action open_action target_list command_wrapper ssh_command_wrapper log_levels io_logger log string bootstrap local_config config test_config_loader node_with_script_hooks partition_hierarchy_node host hostgroup tree partition test_partition key_generator key_saver keystore runtime_config key_info_action dump_key_action }.each {|f| require "arver/#{f}" }
5
+ %w{ gpg_key_manager luks_wrapper action initial_config_action refresh_action create_action list_action gc_action adduser_action deluser_action info_action close_action open_action systemd_open_action target_list command_wrapper ssh_command_wrapper log_levels io_logger log string bootstrap local_config config test_config_loader node_with_script_hooks partition_hierarchy_node host hostgroup tree partition test_partition key_generator key_saver keystore runtime_config key_info_action dump_key_action }.each {|f| require "arver/#{f}" }
6
6
 
7
+ ROOT_DIR = File.expand_path('../..',__FILE__)
data/man/arver.5 CHANGED
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "ARVER" "5" "August 2012" "" ""
4
+ .TH "ARVER" "5" "January 2022" "" ""
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBarver\fR \- LUKS on the loose
@@ -46,6 +46,10 @@ Creates LUKS partitions for \fBarver\fR on all targeted disks\.
46
46
  Opens all targeted disks\.
47
47
  .
48
48
  .TP
49
+ \fB\-\-systemd\-open TARGET\fR
50
+ Same as above, but supplying password to systemd ask\-password, used during system startup\.
51
+ .
52
+ .TP
49
53
  \fB\-\-close TARGET\fR
50
54
  Closes all targeted disks\.
51
55
  .
@@ -327,6 +331,22 @@ Those scripts have to be present at the actual host\.
327
331
  .P
328
332
  If you don\'t have a key for any of the disks that you wish to open it will be skipped (along with its script hooks)\.
329
333
  .
334
+ .P
335
+ Arver can also open a disk that is waiting for a password by systemd\-ask\-password\. Typically this is happening during startup of a physical system, e\.g\., within the initrd\. For that there is a special mode called:
336
+ .
337
+ .IP "" 4
338
+ .
339
+ .nf
340
+
341
+ $ arver \-\-systemd\-open TARGET
342
+ .
343
+ .fi
344
+ .
345
+ .IP "" 0
346
+ .
347
+ .P
348
+ Note, due to the provided api by systemd, there is unfortunately no indication if the command suceeded\. Typically unlocking the last pending disk automatically continues booting the server\. In case the inird ssh has a differen hostname or address than the acutal system, there is an optional \fBboot_address\fR config in the disks configuration, to override the default one\. This mode expects ssh to be on port 22 and user root\.
349
+ .
330
350
  .SH "Action Close"
331
351
  Closing luks devices is simply done by invoking
332
352
  .
Binary file
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: arver
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.8
4
+ version: 0.1.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - o
8
8
  - andreas
9
9
  - mh
10
- autorequire:
10
+ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2020-03-02 00:00:00.000000000 Z
13
+ date: 2022-01-29 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: gpgme
@@ -128,16 +128,18 @@ files:
128
128
  - lib/arver/runtime_config.rb
129
129
  - lib/arver/ssh_command_wrapper.rb
130
130
  - lib/arver/string.rb
131
+ - lib/arver/systemd_open_action.rb
131
132
  - lib/arver/target_list.rb
132
133
  - lib/arver/test_config_loader.rb
133
134
  - lib/arver/test_partition.rb
134
135
  - lib/arver/tree.rb
135
136
  - lib/arver/version.rb
136
137
  - man/arver.5
138
+ - vendor/password-agent
137
139
  homepage: https://code.immerda.ch/immerda/apps/arver
138
140
  licenses: []
139
141
  metadata: {}
140
- post_install_message:
142
+ post_install_message:
141
143
  rdoc_options: []
142
144
  require_paths:
143
145
  - lib
@@ -152,8 +154,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
152
154
  - !ruby/object:Gem::Version
153
155
  version: 1.3.6
154
156
  requirements: []
155
- rubygems_version: 3.0.6
156
- signing_key:
157
+ rubygems_version: 3.1.2
158
+ signing_key:
157
159
  specification_version: 4
158
160
  summary: LUKS for groups
159
161
  test_files: []