vines-agent 0.1.1 → 0.1.2

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.
@@ -23,6 +23,11 @@ module Vines
23
23
  jid = Blather::JID.new(fqdn, domain, 'vines')
24
24
  @stream = Blather::Client.setup(jid, password, host, port, certs)
25
25
 
26
+ @stream.register_handler(:stream_error) do |e|
27
+ log.error(e.message)
28
+ true # prevent EM.stop
29
+ end
30
+
26
31
  @stream.register_handler(:disconnected) do
27
32
  log.info("Stream disconnected, reconnecting . . .")
28
33
  EM::Timer.new(rand(16) + 5) do
@@ -35,6 +40,7 @@ module Vines
35
40
  # prevent handler called twice
36
41
  unless @ready
37
42
  log.info("Connected #{@stream.jid} agent to #{host}:#{port}")
43
+ log.warn("Agent must run as root user to allow user switching") unless root?
38
44
  @ready = true
39
45
  startup
40
46
  end
@@ -270,6 +276,12 @@ module Vines
270
276
  def from_service?(node)
271
277
  @services.include?(node.from.stripped.to_s.downcase)
272
278
  end
279
+
280
+ # Return true if the agent process is owned by root. Switching users with
281
+ # +v user+ is only possible when running as root.
282
+ def root?
283
+ Process.uid == 0
284
+ end
273
285
  end
274
286
  end
275
287
  end
@@ -17,8 +17,8 @@ module Vines
17
17
  # commands.
18
18
  def initialize(jid, permissions)
19
19
  @jid, @permissions = jid, permissions
20
- @user, @commands = allowed_users.first, EM::Queue.new
21
- spawn(@user)
20
+ @user = allowed_users.first if allowed_users.size == 1
21
+ @commands = EM::Queue.new
22
22
  process_command_queue
23
23
  end
24
24
 
@@ -55,7 +55,10 @@ module Vines
55
55
  end
56
56
 
57
57
  def run_in_slave(command)
58
+ return "-> no user selected, run 'v user'" unless @user
58
59
  log.info("Running #{command} as #{@user}")
60
+
61
+ spawn(@user) unless @shell
59
62
  out, err = @shell.execute(command)
60
63
  output = [].tap do |arr|
61
64
  arr << out if out && !out.empty?
@@ -63,16 +66,21 @@ module Vines
63
66
  end.join("\n")
64
67
  output.empty? ? '-> command completed' : output
65
68
  rescue
66
- spawn(@user)
69
+ close
67
70
  '-> restarted shell'
68
71
  end
69
72
 
73
+ def close
74
+ @slave.shutdown(quiet: true) if @slave
75
+ @slave = @shell = nil
76
+ end
77
+
70
78
  # Fork a child process in which to run a shell as this user. Return
71
79
  # the slave and its remote shell proxy. The agent process must be run
72
80
  # as root for the user switch to work.
73
81
  def spawn(user)
74
82
  log.info("Starting shell as #{user}")
75
- @slave.shutdown(quiet: true) if @slave
83
+ close
76
84
  Thread.new do # so em thread won't die on @slave.shutdown
77
85
  slave = Slave.new(psname: "vines-session-#{user}") do
78
86
  uid = Process.euid
@@ -95,7 +103,7 @@ module Vines
95
103
  shell
96
104
  end
97
105
  File.chmod(0700, slave.socket)
98
- @slave, @shell = [slave, slave.object]
106
+ @slave, @shell = slave, slave.object
99
107
  end.join
100
108
  end
101
109
 
@@ -112,21 +120,49 @@ module Vines
112
120
  def run_built_in(command)
113
121
  _, command, *args = command.strip.split(/\s+/)
114
122
  case command
115
- when 'user' then user_command(args)
116
- when 'reset' then reset_command(args)
117
- else '-> not a vines command'
123
+ when 'user' then user_command(args)
124
+ when 'reset' then reset_command(args)
125
+ when 'version' then version_command(args)
126
+ when 'help' then help_command(args)
127
+ else '-> usage: v user|reset|version|help'
118
128
  end
119
129
  end
120
130
 
131
+ def help_command(args)
132
+ [
133
+ "Usage:",
134
+ " v user [name] Display the current user or switch users.",
135
+ " v reset Stops the shell session and starts a new one.",
136
+ " v version Display the agent's version.",
137
+ " v help Provide help on vines commands."
138
+ ].join("\n")
139
+ end
140
+
141
+ def version_command(args)
142
+ return "-> usage: v version" unless args.empty?
143
+ Vines::Agent::VERSION
144
+ end
145
+
121
146
  # Run the +v user+ built-in vines command to list or change the current
122
147
  # unix account executing shell commands.
123
148
  def user_command(args)
124
- return "-> current: #{@user}\n allowed: #{allowed_users.join(', ')}" if args.empty?
125
149
  return "-> usage: v user [name]" if args.size > 1
126
- return "-> user switch not allowed" unless allowed?(args.first)
127
- @user = args.first
128
- spawn(@user)
129
- "-> switched user to #{@user}"
150
+
151
+ if args.empty?
152
+ current = @user || '<none>'
153
+ allowed = allowed_users.empty? ? '<none>' : allowed_users.join(', ')
154
+ return "-> current: #{current}\n allowed: #{allowed}"
155
+ end
156
+
157
+ user = args.first
158
+ if allowed?(user)
159
+ @user = user
160
+ close
161
+ "-> switched user to #{@user}"
162
+ else
163
+ log.warn("#{@jid} denied access to #{user}")
164
+ "-> user switch not allowed"
165
+ end
130
166
  end
131
167
 
132
168
  def reset?(command)
@@ -137,7 +173,7 @@ module Vines
137
173
  def reset_command(args)
138
174
  return "-> usage: v reset" unless args.empty?
139
175
  @commands = EM::Queue.new
140
- spawn(@user)
176
+ close
141
177
  process_command_queue
142
178
  "-> reset shell"
143
179
  end
@@ -145,21 +181,30 @@ module Vines
145
181
  # Return true if the current JID is allowed to run commands as the given
146
182
  # user name on this system.
147
183
  def allowed?(user)
148
- jids = @permissions[user] || []
149
- valid = jids.include?(@jid) && exists?(user)
150
- log.warn("#{@jid} denied access to #{user}") unless valid
151
- valid
184
+ allowed = (@permissions[user] || []).include?(@jid)
185
+ allowed && exists?(user) && (root? || current?(user))
186
+ end
187
+
188
+ # Return true if the agent process is owned by root. Switching users with
189
+ # +v user+ is only possible when running as root.
190
+ def root?
191
+ Process.uid == 0
192
+ end
193
+
194
+ # Return true if the user name is the current agent process owner.
195
+ def current?(user)
196
+ Process.uid == Etc.getpwnam(user).uid
197
+ rescue
198
+ false
152
199
  end
153
200
 
154
201
  def exists?(user)
155
- Etc::getpwnam(user) rescue false
202
+ Etc.getpwnam(user) rescue false
156
203
  end
157
204
 
158
205
  # Return the list of unix user accounts this user is allowed to access.
159
206
  def allowed_users
160
- @permissions.select do |unix, jids|
161
- jids.include?(@jid) && exists?(unix)
162
- end.keys.sort
207
+ @permissions.keys.sort.select {|unix| allowed?(unix) }
163
208
  end
164
209
  end
165
210
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Vines
4
4
  module Agent
5
- VERSION = '0.1.1'
5
+ VERSION = '0.1.2'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vines-agent
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-10-20 00:00:00.000000000Z
12
+ date: 2011-10-28 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: blather
16
- requirement: &70352868783740 !ruby/object:Gem::Requirement
16
+ requirement: &70257751095360 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 0.5.8
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70352868783740
24
+ version_requirements: *70257751095360
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: ohai
27
- requirement: &70352868782180 !ruby/object:Gem::Requirement
27
+ requirement: &70257751094400 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 0.6.8
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70352868782180
35
+ version_requirements: *70257751094400
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: session
38
- requirement: &70352868780480 !ruby/object:Gem::Requirement
38
+ requirement: &70257751093700 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: 3.1.0
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70352868780480
46
+ version_requirements: *70257751093700
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: slave
49
- requirement: &70352868778940 !ruby/object:Gem::Requirement
49
+ requirement: &70257751092940 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 1.3.0
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *70352868778940
57
+ version_requirements: *70257751092940
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: vines
60
- requirement: &70352868777680 !ruby/object:Gem::Requirement
60
+ requirement: &70257751092280 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ~>
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '0.3'
66
66
  type: :runtime
67
67
  prerelease: false
68
- version_requirements: *70352868777680
68
+ version_requirements: *70257751092280
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: minitest
71
- requirement: &70352865325120 !ruby/object:Gem::Requirement
71
+ requirement: &70257751091680 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: '0'
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *70352865325120
79
+ version_requirements: *70257751091680
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: rake
82
- requirement: &70352865324580 !ruby/object:Gem::Requirement
82
+ requirement: &70257751091220 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
@@ -87,7 +87,7 @@ dependencies:
87
87
  version: '0'
88
88
  type: :development
89
89
  prerelease: false
90
- version_requirements: *70352865324580
90
+ version_requirements: *70257751091220
91
91
  description: ! 'Vines Agent executes shell commands sent by users after
92
92
 
93
93
  authorizing them against an access control list, provided by the Vines Services