train-core 3.15.2 → 3.16.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 93eb56f75bd0bb4445766f711e0c6a4bc9c9b4b7dcdbce27065cdbe1d77f173a
4
- data.tar.gz: 48da5db98b20cc50e46a76f7c293fc3d7c659073081a3ac5d3e5b1e0bad6aa8b
3
+ metadata.gz: 8c128201cccb279232b166336df2264fa69d23d4244678a25c46ec1ecf72a47b
4
+ data.tar.gz: bed78ce368487e2e220d5b5361f49f20ed2d4483f2033b4800dff57cd07a0e4a
5
5
  SHA512:
6
- metadata.gz: 15d5e62ef1c5e23f91a49f23a358f27d1b7e3297614419d5b15dedc9b25ec9848881b1c955693d75c2b5eece7783829c376210dc52d69ba92754cb1ba134f07a
7
- data.tar.gz: da106c56945fa66b0bf01917276bf9bc5b694787c7e4b1a1cfdb8ff6c9e73a6f737c0a98e7df0f5d1f656c936e9dc388ec19db967733ecd197cb47e0fa012c83
6
+ metadata.gz: 1ca1fc41aabfd604cf2e7cd9d8ac7cf64f733d29a96b8a7b8c48e608b7f88a30627009a51a7f6fc47c99f012db153fbdee8736e94f35ad8954fdb74b0b92f2f9
7
+ data.tar.gz: 15fb4bef30b0391a70c6fce30e41b836101e6d9181bc93ab30838023b5cb86a4c00e18bfe7b8bb715f916b1702eed79d86135440ac629332e74f69b5abd7b79d
@@ -229,11 +229,28 @@ module Train::Transports
229
229
  at_exit { close rescue Errno::EIO }
230
230
 
231
231
  pipe = nil
232
+ ownership_verified = false
232
233
 
233
234
  # PowerShell needs time to create pipe.
234
235
  100.times do
236
+ unless ownership_verified
237
+ owner, current_user, is_owner = pipe_owned_by_current_user?(pipe_name)
238
+ if owner.nil?
239
+ sleep 0.1
240
+ next
241
+ end
242
+
243
+ unless is_owner
244
+ raise PipeError, "Unauthorized user '#{current_user}' tried to connect to pipe '#{pipe_name}'. Pipe is owned by '#{owner}'."
245
+ end
246
+
247
+ ownership_verified = true
248
+ end
249
+
235
250
  pipe = open("//./pipe/#{pipe_name}", "r+")
236
251
  break
252
+ rescue PipeError
253
+ raise
237
254
  rescue
238
255
  sleep 0.1
239
256
  end
@@ -246,17 +263,30 @@ module Train::Transports
246
263
 
247
264
  script = <<-EOF
248
265
  $ErrorActionPreference = 'Stop'
266
+ $ProgressPreference = 'SilentlyContinue'
267
+ $user = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
268
+ $pipeSecurity = New-Object System.IO.Pipes.PipeSecurity
269
+ $rule = New-Object System.IO.Pipes.PipeAccessRule($user, "FullControl", "Allow")
270
+ $pipeSecurity.AddAccessRule($rule)
271
+ $pipeServer = New-Object System.IO.Pipes.NamedPipeServerStream('#{pipe_name}', [System.IO.Pipes.PipeDirection]::InOut, 1, [System.IO.Pipes.PipeTransmissionMode]::Byte, [System.IO.Pipes.PipeOptions]::None, 4096, 4096, $pipeSecurity)
272
+
273
+ try {
274
+ $pipeServer.WaitForConnection()
275
+ } catch {
276
+ exit 1
277
+ }
249
278
 
250
- $pipeServer = New-Object System.IO.Pipes.NamedPipeServerStream('#{pipe_name}')
251
279
  $pipeReader = New-Object System.IO.StreamReader($pipeServer)
252
280
  $pipeWriter = New-Object System.IO.StreamWriter($pipeServer)
253
281
 
254
- $pipeServer.WaitForConnection()
255
-
256
282
  # Create loop to receive and process user commands/scripts
257
283
  $clientConnected = $true
258
284
  while($clientConnected) {
259
285
  $input = $pipeReader.ReadLine()
286
+ if ($input -eq $null) {
287
+ $clientConnected = $false
288
+ break
289
+ }
260
290
  $command = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($input))
261
291
 
262
292
  # Execute user command/script and convert result to JSON
@@ -278,8 +308,14 @@ module Train::Transports
278
308
 
279
309
  # Encode JSON in Base64 and write to pipe
280
310
  $encodedResult = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($resultJSON))
281
- $pipeWriter.WriteLine($encodedResult)
282
- $pipeWriter.Flush()
311
+ try {
312
+ $pipeWriter.WriteLine($encodedResult)
313
+ $pipeWriter.Flush()
314
+ } catch [System.IO.IOException] {
315
+ # Pipe was closed by client, exit gracefully
316
+ $clientConnected = $false
317
+ break
318
+ }
283
319
  }
284
320
  EOF
285
321
 
@@ -288,6 +324,29 @@ module Train::Transports
288
324
  cmd = "#{@powershell_cmd} -NoProfile -ExecutionPolicy bypass -NonInteractive -EncodedCommand #{base64_script}"
289
325
  Process.create(command_line: cmd).process_id
290
326
  end
327
+
328
+ def current_windows_user
329
+ user = `powershell -Command "[System.Security.Principal.WindowsIdentity]::GetCurrent().Name"`.strip
330
+ if user.nil? || user.empty?
331
+ user = `whoami`.strip
332
+ end
333
+ if user.nil? || user.empty?
334
+ raise "Unable to determine current Windows user"
335
+ end
336
+
337
+ user
338
+ end
339
+
340
+ # Verify pipe ownership before connecting
341
+ def pipe_owned_by_current_user?(pipe_name)
342
+ exists = `powershell -Command "Test-Path \\\\.\\pipe\\#{pipe_name}"`.strip.downcase == "true"
343
+ current_user = current_windows_user
344
+ return [nil, current_user, false] unless exists
345
+
346
+ owner = `powershell -Command "(Get-Acl \\\\.\\pipe\\#{pipe_name}).Owner" 2>&1`.strip
347
+ is_owner = !owner.nil? && !current_user.nil? && owner.casecmp(current_user) == 0
348
+ [owner, current_user, is_owner]
349
+ end
291
350
  end
292
351
  end
293
352
  end
data/lib/train/version.rb CHANGED
@@ -2,5 +2,5 @@
2
2
  # Author:: Dominik Richter (<dominik.richter@gmail.com>)
3
3
 
4
4
  module Train
5
- VERSION = "3.15.2".freeze
5
+ VERSION = "3.16.1".freeze
6
6
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: train-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.15.2
4
+ version: 3.16.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chef InSpec Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-01-09 00:00:00.000000000 Z
11
+ date: 2026-01-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable