Skip Menu |

This queue is for tickets about the Net-VNC CPAN distribution.

Report information
The Basics
Id: 70039
Status: resolved
Priority: 0/
Queue: Net-VNC

People
Owner: Nobody in particular
Requestors: maurice [...] mon1.ipx.com.au
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: Net::VNC cannot capture images from OS X Lion
Date: Fri, 5 Aug 2011 21:55:31 +1000 (EST)
To: bug-Net-VNC [...] rt.cpan.org
From: User Maurice <maurice [...] mon1.ipx.com.au>
It appears that the introduction of multi-user VNC access on OS X 10.7 Lion has broken screen capture by Net::VNC. The fault manifests itself as: Connection failed at /usr/local/lib/perl5/site_perl/5.10.1/Net/VNC.pm line 254. Many thanks Maurice Castro
From: maurice [...] castro.aus.net
A solution is attached as a patch to 0.38 Net::VNC.pm This patch adds ARD log in based on username and password. It requires an extra authentication field to be set (username) before connecting On Fri Aug 05 07:56:48 2011, maurice@mon1.ipx.com.au wrote: Show quoted text
> It appears that the introduction of multi-user VNC access on OS X 10.7 > Lion has broken screen capture by Net::VNC. The fault manifests itself > as: > > Connection failed at /usr/local/lib/perl5/site_perl/5.10.1/Net/VNC.pm > line 254. > > Many thanks > Maurice Castro
Subject: ard.diff
--- VNC.pm 2011-08-09 10:38:52.000000000 +1000 +++ VNC.pm 2011-09-02 09:31:51.000000000 +1000 @@ -3,11 +3,13 @@ use warnings; use base qw(Class::Accessor::Fast); use Crypt::DES; +use Crypt::GCrypt::MPI; +use Crypt::Random; use Image::Imlib2; use IO::Socket::INET; use bytes; __PACKAGE__->mk_accessors( - qw(hostname port password socket name width height depth save_bandwidth + qw(hostname port password username socket name width height depth save_bandwidth hide_cursor server_endian _pixinfo _colourmap _framebuffer _cursordata _rfb_version _bpp _true_colour _big_endian _image_format @@ -236,7 +238,10 @@ push @security_types, $security_type; } - for my $preferred_type ( 2, 1 ) { + my @pref_types = (1,2); + @pref_types = (30,1,2) if ($self->username); + + for my $preferred_type (@pref_types) { if ( 0 < grep { $_ == $preferred_type } @security_types ) { $security_type = $preferred_type; last; @@ -300,6 +305,60 @@ if ( $self->_rfb_version ge '003.007' ) { $socket->print( pack( 'C', 1 ) ); } + + } elsif ( $security_type == 30 ) { + + # ARD - Apple Remote Desktop - authentication + $socket->print( pack( 'C', 30 ) ); # use ARD + $socket->read( my $gen, 2 ) || die 'unexpected end of data'; + $socket->read( my $len, 2 ) || die 'unexpected end of data'; + my $keylen = _bin_int($len); + $socket->read( my $mod, $keylen ) || die 'unexpected end of data'; + $socket->read( my $resp, $keylen ) || die 'unexpected end of data'; + + my $genmpi = Crypt::GCrypt::MPI::new(secure => 0, value => _bin_int($gen), format => Crypt::GCrypt::MPI::FMT_USG); + my $modmpi = Crypt::GCrypt::MPI::new(secure => 0, value => $mod, format => Crypt::GCrypt::MPI::FMT_USG); + my $respmpi = Crypt::GCrypt::MPI::new(secure => 0, value => $resp, format => Crypt::GCrypt::MPI::FMT_USG); + my $privmpi = _mpi_randomize($keylen); + + my $pubmpi = $genmpi->copy()->powm($privmpi,$modmpi); + my $keympi = $respmpi->copy()->powm($privmpi,$modmpi); + my $pub = _mpi_2_bytes($pubmpi, $keylen); + my $key = _mpi_2_bytes($keympi, $keylen); + my $md5 = Crypt::GCrypt->new( type => 'digest', algorithm => 'md5'); + $md5->write($key); + my $shared = $md5->read(); + my $passlen = length($self->password) + 1; + my $userlen = length($self->username) + 1; + $passlen = 64 if ($passlen > 64); + my $passpad = 64 - $passlen; + $userlen = 64 if ($userlen > 64); + my $userpad = 64 - $userlen; + my $up = Crypt::Random::makerandom_octet(Length => $userpad, Strength => 1); + my $pp = Crypt::Random::makerandom_octet(Length => $passpad, Strength => 1); + my $userpass = pack "a*xa*a*xa*", $self->username, $up, $self->password, $pp; + my $aes = Crypt::GCrypt->new(type => 'cipher', algorithm => 'aes', mode => 'ecb'); + $aes->start('encrypting'); + $aes->setkey($shared); + my $cyptxt = $aes->encrypt($userpass); + $cyptxt .= $aes->finish; + $socket->write($cyptxt,128); # appears to be only writing 16 bytes + $socket->write($pub, $keylen); # appears to be only writing 16 bytes + $socket->read( my $security_result, 4 ) + || die 'unexpected end of data'; + $security_result = _bin_int($security_result); + + if ($security_result == 1) + { + $socket->read( my $len, 4 ) || die 'unexpected end of data'; + $socket->read( my $msg, _bin_int($len) ) || die 'unexpected end of data'; + die "VNC Authentication Failed: $msg"; + } + elsif ($security_result == 2) + { + # too many + die "VNC Authentication Failed - too many tries"; + } } else { @@ -323,6 +382,53 @@ } } +sub _mpi_randomize { + my ($l) = @_; + my $bits = int ($l / 8) * 8; + my $bytes = int ($bits / 8); + my $r = Crypt::Random::makerandom_octet(Length => $bytes, Strength => 1); + my @ra = unpack("C*", $r); + my $mpi = Crypt::GCrypt::MPI::new(secure => 0, value => 0); + my $tfs = Crypt::GCrypt::MPI::new(secure => 0, value => 256); + for (my $i = 0; $i < $bytes; $i++) + { + $mpi = $mpi->mul($tfs); + my $n = $ra[$i]; + $mpi = $mpi->add( Crypt::GCrypt::MPI::new(secure => 0, value => $n)); + } + return $mpi; +} + +sub _mpi_2_bytes { + my ($mpi, $sz) = @_; + my $s = $mpi->print(Crypt::GCrypt::MPI::FMT_USG); + my $pad = $sz - length($s); + return pack("x[$pad]a*",$s); +} + +sub _fmt_hex { + my ($s) = @_; + my @a = unpack("C*", $s); + my $r = 0; + for (my $i = 0 ; $i < @a; $i++) + { + $r .= sprintf("%02X",$a[$i]); + } + return $r; +} + +sub _bin_int { + my ($s) = @_; + my @a = unpack("C*", $s); + my $r = 0; + for (my $i = 0 ; $i < @a; $i++) + { + $r = 256 * $r; + $r += $a[$i]; + } + return $r; +} + sub _client_initialization { my $self = shift; @@ -1058,7 +1164,8 @@ my $vnc = Net::VNC->new({hostname => $hostname, password => $password}); -Optionally, you can also specify a port, which defaults to 5900. +Optionally, you can also specify a port, which defaults to 5900. For ARD +(Apple Remote Desktop) authenticaion you must also specify a username. =head2 login @@ -1200,6 +1307,10 @@ Chris Dolan clotho@cpan.org +Apple Remote Desktop authentication based on LibVNCServer + +Maurice Castro maurice@ipexchange.com.au + Many thanks for Foxtons Ltd for giving Leon the opportunity to write the original version of this module.
Thanks for the patch! I've released Net-VNC-0.39.tar.gz to CPAN incorporating your patch with a few modifications. Please let me know if all is well. Cheers, Leon.