[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Gnupg and ruby

Dominik Werder

1/28/2005 3:41:00 PM

Hello!

I tried to use the command line gnu privacy guard with ruby.

The first attempt works quite good, using the Open3 lib:

i,o,e=Open3.popen3 "gpg --batch -ea"
i.puts ciphertext
i.close
o.each do |s|
puts "Out: " << s
end
e.each do |s|
puts "Err: " << s
end
o.close
e.close


But if I want language independant error codes then I have to pass gpg
some file descriptor numbers like:
gpg --no-tty --command-fd 14 --status-fd 15 --logger-fd 16


My question is: How do I create such pipes?

I already tried IO.pipe but gpg seems to not like them..
I also tried creating fifos but this doesn't work either..

Any hints appreciated!

bye!
Dominik
3 Answers

Michael Neumann

1/28/2005 4:27:00 PM

0

Dominik Werder wrote:
> Hello!
>
> I tried to use the command line gnu privacy guard with ruby.
>
> The first attempt works quite good, using the Open3 lib:
>
> i,o,e=Open3.popen3 "gpg --batch -ea"
> i.puts ciphertext
> i.close
> o.each do |s|
> puts "Out: " << s
> end
> e.each do |s|
> puts "Err: " << s
> end
> o.close
> e.close
>
>
> But if I want language independant error codes then I have to pass gpg
> some file descriptor numbers like:
> gpg --no-tty --command-fd 14 --status-fd 15 --logger-fd 16
>
>
> My question is: How do I create such pipes?

Not sure about this either. Maybe it would work if you fork the process,
then open some files and use their #fileno as value, and then use exec
to replace the running process with the gpg program. But that's pure
speculation...

Regards,

Michael


Sam Roberts

1/28/2005 11:20:00 PM

0

Wrote Dominik Werder <dwerder@gmx.net>, on Sat, Jan 29, 2005 at 12:40:52AM +0900:
> Hello!
>
> I tried to use the command line gnu privacy guard with ruby.
>
> The first attempt works quite good, using the Open3 lib:
>
> i,o,e=Open3.popen3 "gpg --batch -ea"
> i.puts ciphertext
> i.close
> o.each do |s|
> puts "Out: " << s
> end
> e.each do |s|
> puts "Err: " << s
> end
> o.close
> e.close
>
>
> But if I want language independant error codes then I have to pass gpg
> some file descriptor numbers like:
> gpg --no-tty --command-fd 14 --status-fd 15 --logger-fd 16
>
>
> My question is: How do I create such pipes?
>
> I already tried IO.pipe but gpg seems to not like them..

I just know how to do this in C, not ruby, but if no one has better
information, maybe these suggestions will help.

What did you do?

read, write = IO.pipe

if you do

cmd = File.popen("cmd --read-from #{read.fileno}")

and then do

read.close
write.print(..)

This didn't work?

Another approach would be to create the pipes, call Process.fork, parent
closes the read pipes, child closes the write pipes, then try and write
from parent to child (which are both still ruby).

If that works, have the child Kernel#exec gpg.

It works for me:

#!/usr/bin/ruby -w

r, w = IO.pipe

Kernel.fork do
# child
w.close

# you would do an exec, here.
puts "rd from #{r.fileno}"
puts "rd -> #{r.readline}"

exit 0
end

# parent

r.close

puts "wr on #{w.fileno}"

w.write("hello, chile\n")

Process.wait

exit 0

--
Sam Roberts <sroberts@certicom.com>


Dominik Werder

1/29/2005 10:56:00 AM

0

I think I found my problem..
I assumed that gpg expects the data on the command-fd but that seems to be
wrong. If I use stdin of the gpg process to write my plaintext it works
and I get these error codes I was looking for, here's my code:

At the moment it encrypts to the default receiver specified in my gpg
options file, therefore no -r switch for the gpg command..


require 'open3'
msg=<<EOS
A little test message..
EOS
ii,i=IO.pipe # commands to gpg
o,oo=IO.pipe # status and data from gpg
e,ee=IO.pipe # errors from gpg
cmd="gpg --no-tty --status-fd #{oo.fileno} --logger-fd #{ee.fileno} "+
"--command-fd #{ii.fileno} -ea"
puts cmd
iii,ooo,eee = Open3.popen3 cmd
success=false
iii.puts msg
iii.close
require 'timeout'
begin
Timeout::timeout 4 do
o.each do |s|
puts "Out: #{s}"
if s=~/END_ENCRYPTION/
success=true
break
elsif s=~/NODATA/
break
end
end
ooo.each do |s|
puts "OOOut: #{s}"
end
end
rescue Timeout::Error=>e
puts 'Encryption timeout'
end
puts success ? 'Decryption OK' : 'Decryption failed'