train-core 3.15.2 → 3.16.0

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: f539d85c4bc8d03bd8892d11fdd131db8e8ba62a4d478ba89c056e122167a8ba
4
+ data.tar.gz: 41171d85c20e5420efefec62dd5a312ea9768921283d9c34431b6fd604762401
5
5
  SHA512:
6
- metadata.gz: 15d5e62ef1c5e23f91a49f23a358f27d1b7e3297614419d5b15dedc9b25ec9848881b1c955693d75c2b5eece7783829c376210dc52d69ba92754cb1ba134f07a
7
- data.tar.gz: da106c56945fa66b0bf01917276bf9bc5b694787c7e4b1a1cfdb8ff6c9e73a6f737c0a98e7df0f5d1f656c936e9dc388ec19db967733ecd197cb47e0fa012c83
6
+ metadata.gz: 9e1ec8264a1b3ed12ec9e667d28cdeeea4ddf90b658b727f69233a93ce34abe16444509d9e85037fb418bc404d423ad636fa8eba94e49be2ffc9982300bd704f
7
+ data.tar.gz: c513db316ea377f56fb1096713743191e5817e85797ff2307ec9bcbfa904e30c8a8cedb6e516a0dae14ac660dcc418d6f80ba8fae291dfab4b55d849e0dddead
@@ -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,26 @@ 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
+ $pipeServer.WaitForConnection()
249
274
 
250
- $pipeServer = New-Object System.IO.Pipes.NamedPipeServerStream('#{pipe_name}')
251
275
  $pipeReader = New-Object System.IO.StreamReader($pipeServer)
252
276
  $pipeWriter = New-Object System.IO.StreamWriter($pipeServer)
253
277
 
254
- $pipeServer.WaitForConnection()
255
-
256
278
  # Create loop to receive and process user commands/scripts
257
279
  $clientConnected = $true
258
280
  while($clientConnected) {
259
281
  $input = $pipeReader.ReadLine()
282
+ if ($input -eq $null) {
283
+ $clientConnected = $false
284
+ break
285
+ }
260
286
  $command = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($input))
261
287
 
262
288
  # Execute user command/script and convert result to JSON
@@ -278,8 +304,14 @@ module Train::Transports
278
304
 
279
305
  # Encode JSON in Base64 and write to pipe
280
306
  $encodedResult = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($resultJSON))
281
- $pipeWriter.WriteLine($encodedResult)
282
- $pipeWriter.Flush()
307
+ try {
308
+ $pipeWriter.WriteLine($encodedResult)
309
+ $pipeWriter.Flush()
310
+ } catch [System.IO.IOException] {
311
+ # Pipe was closed by client, exit gracefully
312
+ $clientConnected = $false
313
+ break
314
+ }
283
315
  }
284
316
  EOF
285
317
 
@@ -288,6 +320,29 @@ module Train::Transports
288
320
  cmd = "#{@powershell_cmd} -NoProfile -ExecutionPolicy bypass -NonInteractive -EncodedCommand #{base64_script}"
289
321
  Process.create(command_line: cmd).process_id
290
322
  end
323
+
324
+ def current_windows_user
325
+ user = `powershell -Command "[System.Security.Principal.WindowsIdentity]::GetCurrent().Name"`.strip
326
+ if user.nil? || user.empty?
327
+ user = `whoami`.strip
328
+ end
329
+ if user.nil? || user.empty?
330
+ raise "Unable to determine current Windows user"
331
+ end
332
+
333
+ user
334
+ end
335
+
336
+ # Verify pipe ownership before connecting
337
+ def pipe_owned_by_current_user?(pipe_name)
338
+ exists = `powershell -Command "Test-Path \\\\.\\pipe\\#{pipe_name}"`.strip.downcase == "true"
339
+ current_user = current_windows_user
340
+ return [nil, current_user, false] unless exists
341
+
342
+ owner = `powershell -Command "(Get-Acl \\\\.\\pipe\\#{pipe_name}).Owner" 2>&1`.strip
343
+ is_owner = !owner.nil? && !current_user.nil? && owner.casecmp(current_user) == 0
344
+ [owner, current_user, is_owner]
345
+ end
291
346
  end
292
347
  end
293
348
  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.0".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.0
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-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable