Schrift
[thread]8249[/thread]

Hash Struktur senden: Client - Server

Leser: 1


<< |< 1 2 3 4 >| >> 31 Einträge, 4 Seiten
bloonix
 2006-08-20 07:23
#69014 #69014
User since
2005-12-17
1615 Artikel
HausmeisterIn
[Homepage]
user image
Hallo Community,

um eine große Hashstruktur von einem Client zum Server zu übermitteln,
habe ich mir ein paar Module angesehen und Sie auch ausprobiert:

* YAML
* JSON
* Data::Dumper + Safe

Mit allen drei Möglichkeiten ist es recht einfach eine Hash-Struktur mit
dem Client zu zerlegen und sie mit dem Server wieder aufzubauen.
Allerdings habe ich so einige Bedenken und vielleicht habt Ihr ein paar
Tipps für mich.

Also die Bugliste von YAML ist ziemlich groß und ich habe einfach ein
ungutes Gefühl es zu benutzen, allerdings soll YAML sehr sicher sein,
was den Wiederaufbau der Hashstruktur angeht (untaint).

JSON hat auf mich großen Eindruck gemacht, da es wohl sehr beliebt zu
sein scheint. Das Einzige, was mich störte war, dass ich ettliche andere
Module hierfür installieren musste. Zudem weiß ich auch nicht wie sicher
JSON ist, wenn Objekte wiederhergestellt werden (jsonToObj).

Data::Dumper ist ja allgemein bekannt und das Modul macht mir soweit
keine Sorgen, allerdings rätsel ich noch immer ein wenig mit Safe rum und
ob es tatsächlich so sicher ist, mittels reval() den Hash aufzubauen.

Also mein Hauptproblem ist nicht das versenden der Daten, denn das
können alle drei Module, mir geht es vielmehr um die Sicherheit des
Wiederaufbaus der Datenstruktur auf dem Server und das kein unsicherer
Code eingeschleusst werden kann. Also alles, was mit eval() zu tun hat
gefällt mir nicht so recht.

Gibt es vielleicht noch andere Möglichkeiten für mich? Eventuell aus dem
XML::* Sortiment?

Grüße,
opi
What is a good module? That's hard to say.
What is good code? That's also hard to say.
One man's Thing of Beauty is another's man's Evil Hack.
Dubu
 2006-08-20 14:17
#69015 #69015
User since
2003-08-04
2145 Artikel
ModeratorIn + EditorIn

user image
Wie wäre es mit Storable?
eval() wird dort nur benötigt, wenn man Subroutinen serialisieren möchte (und das kann man dann in einem Safe Compartment machen).
Strat
 2006-08-20 14:32
#69016 #69016
User since
2003-08-04
5246 Artikel
ModeratorIn
[Homepage] [default_avatar]
wenn binaere uebertragung in frage kommt, koennte CPAN:Storable was fuer dich sein.
perl -le "s::*erlco'unaty.'.dk':e,y;*kn:ai;penmic;;print"
http://www.fabiani.net/
bloonix
 2006-08-20 18:36
#69017 #69017
User since
2005-12-17
1615 Artikel
HausmeisterIn
[Homepage]
user image
Hallo zusammen,

also ich habe CPAN:Storable mal ausprobiert.

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
use strict;
use warnings;

package Server;

use Storable qw(fd_retrieve);
use Data::Dumper;
use IO::Socket::INET;

sub run {
  my $server = IO::Socket::INET->new( LocalPort  => 43610
                                    , Type       => SOCK_STREAM
                                    , Listen     => 10
                                    , Reuse      => 1
                                    ) or die $!;

  while (my $client = $server->accept()) {
     my $data = fd_retrieve($client);
     close $client;
     close $server;
     print Dumper($data);
  }
}

package Client;

use Storable qw(store_fd);
use IO::Socket::INET;

sub run {
  sleep 1;
  my $socket = IO::Socket::INET->new( PeerAddr => '127.0.0.1'
                                    , PeerPort => 43610
                                    , Proto    => 'tcp'
                                    , Type     => SOCK_STREAM
                                    ) or die $!;

  my %hash = (a=>1,b=>2,c=>3);
  store_fd \%hash, $socket;
}

1;

if (my $pid = fork) {
  run Server; waitpid($pid,0);
} else {
  run Client;
}


Gibt es hierbei irgendetwas zu beachten? Wie sicher ist das?

Grüße,
opi
What is a good module? That's hard to say.
What is good code? That's also hard to say.
One man's Thing of Beauty is another's man's Evil Hack.
Dubu
 2006-08-20 23:24
#69018 #69018
User since
2003-08-04
2145 Artikel
ModeratorIn + EditorIn

user image
Für die Kompatbilität zwischen big-endian und little-endian Maschinen sollte man nstore_fd() statt store_fd() benutzen.

Code-Referenzen werden per default nicht (de)serialisiert und auch sonst kein eval() benutzt. Ansonsten ist die Frage: Was meinst du mit "sicher"? Sicher wovor?
bloonix
 2006-08-20 23:54
#69019 #69019
User since
2005-12-17
1615 Artikel
HausmeisterIn
[Homepage]
user image
[quote=Dubu,20.08.2006, 21:24]Für die Kompatbilität zwischen big-endian und little-endian Maschinen sollte man nstore_fd() statt store_fd() benutzen.[/quote]

Jauh, genau das habe ich nachträglich ausgetauscht.

[quote=Dubu,20.08.2006, 21:24]Code-Referenzen werden per default nicht (de)serialisiert und auch sonst kein eval() benutzt. Ansonsten ist die Frage: Was meinst du mit "sicher"?  Sicher wovor?[/quote]

Was bezeichnet man denn allgemein für unsicher? /etc/shadow auslesen,
"rm -rf /" oder ein "iptables -F" ausführen oder irgendwelche Ports öffnen...
Die Client-Server Verbindung ist zwar verschlüsselt, aber man möchte ja
gerne so sicher wie möglich unterwegs sein.

Oder ist das der falsche Ansatz? Vielleicht mache ich es ja trotzdem falsch.
What is a good module? That's hard to say.
What is good code? That's also hard to say.
One man's Thing of Beauty is another's man's Evil Hack.
Dubu
 2006-08-21 01:55
#69020 #69020
User since
2003-08-04
2145 Artikel
ModeratorIn + EditorIn

user image
Nun, wenn man fragt, ob Daten sicher sind, meint man meist Sicherheit vor unberechtigtem Zugriff, vor Manipulation, vor Unterdrückung oder vor Fälschung. (Oder umgekehrt: Man möchte Vertraulichkeit, Integrität, Verfügbarkeit und Authentizität von Daten sicher stellen; die Verbindlichkeit lassen wir hier mal außen vor.)

Deine Beschreibung hört sich so an, als meintest du "sicher vor Lücken in meinem Programm". ;) Eine Software sollte grundsätzlich erstmal von dem Grundsatz ausgehen: "Alles, was von außen kommt, ist unsicher."  Wenn dein Programm so mit den erhaltenen Daten umgeht, dann ist das sicher.

Wenn dein Server natürlich die empfangenen Daten als Liste von Befehlen interpretiert, die als User root ausgeführt werden sollen, dann würde ich mir einige Gedanken darüber machen, wie ich die Datensicherheit gewährleisten kann. Eine verschlüsselte Verbindung ist schon mal nicht schlecht, aber Authentifizierung ist natürlich noch wichtiger. Wenn du dem Übertragungsweg dann vertrauen kannst, ist die Form der Datenrepräsentation nicht so wichtig.

Ein Problem, das direkt mit dem Modul Storable zu tun haben könnte, sehe ich nicht. Storable kümmert sich selber um keinen der o.g. Aspekte, aber es reißt auch keine zusätzlichen Lücken durch eval()s auf, wenn ich die Manpage richtig interpretiere. Vorbehaltlich irgendwelcher Programmierfehler in Storable (oder perl selber) möchte ich behaupten, dass man zumindest davon ausgehen kann, bei einem retrieve() einfach nur Daten geliefert zu bekommen, ohne negative Seiteneffekte.
bloonix
 2006-11-17 12:04
#69021 #69021
User since
2005-12-17
1615 Artikel
HausmeisterIn
[Homepage]
user image
Hallo Community,

nun war ich lange Zeit mit CPAN:Storable sehr sehr zufrieden. Das Modul ist einfach klasse.
Allerdings läuft es nicht mit IO::Socket::SSL. Ich erhalte die Meldung

File is not a perl storable at ../../lib/Storable.pm (autosplit into ../../lib/auto/Storable/fd_retrieve.al) line 346, at ./storable-socket-ssl line 61

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
use strict;
use warnings;

package Server;

use IO::Socket::SSL;
use Storable qw(nstore_fd);
use Data::Dumper;

unless (-d "certs") {
   if (-d "../certs") {
       chdir "..";
   } else {
       die "Please run this example from the IO::Socket::SSL distribution directory!\n";
   }
}

sub run {
  my $socket = IO::Socket::SSL->new(
     Listen => 5,
     LocalAddr => 'localhost',
     LocalPort => 9000,
     Proto     => 'tcp',
     Reuse     => 1,
     SSL_verify_mode => 0x01,
     SSL_passwd_cb => sub {return "bluebell"},
  ) or die "server: can't open socket over port 9000";

  warn "server initialized\n";

  while (my $client = $socket->accept()) {
     chomp (my $request = <$client>);
     next unless $request;
     warn "client request: $request\n";
     my %hash = (a=>1,b=>2,c=>3);
     nstore_fd(\%hash, $client) or die $!;
     close($client);
     close($socket);
  }
}

package Client;

use IO::Socket::SSL;
use Storable qw(fd_retrieve);
use Data::Dumper;

sub run {
  my $socket = IO::Socket::SSL->new(
     PeerAddr => 'localhost',
     PeerPort => '9000',
     Proto    => 'tcp',
     SSL_use_cert => 1,
     SSL_verify_mode => 0x01,
     SSL_passwd_cb => sub { return "opossum" }
  ) or die "client: can't connect to 127.0.0.1:9000";

  warn "client connected to server\n";
  print $socket "hash\n";
  my $data = fd_retrieve($socket) or die $!;
  warn Dumper($data);
  close($socket);
}

1;

if (my $pid = fork) {
  run Server;
  waitpid($pid,0);
} else {
  sleep 1;
  run Client;
}


Dies ist das gleiche Beispiel wie oben, nur halt INET durch SSL ersetzt.

Wenn ich statt

my $data = fd_retrieve($socket) or die $!;

mit

local $/; my $data = <$socket>;

teste, dann ist $data undef.

Hat da jemand Ideen oder kennt eine Lösung?

Gruss,
opi\n\n

<!--EDIT|opi|1163758123-->
What is a good module? That's hard to say.
What is good code? That's also hard to say.
One man's Thing of Beauty is another's man's Evil Hack.
bloonix
 2006-11-17 12:28
#69022 #69022
User since
2005-12-17
1615 Artikel
HausmeisterIn
[Homepage]
user image
Nun suche ich noch nach weiteren Modulen, mit denen man Perlstrukturen
auseinandernehmen und wieder zusammensetzen kann.

Ich habe noch CPAN:XML::Dumper gefunden. Was gibt es sonst noch für Möglichkeiten?\n\n

<!--EDIT|opi|1163759367-->
What is a good module? That's hard to say.
What is good code? That's also hard to say.
One man's Thing of Beauty is another's man's Evil Hack.
bloonix
 2006-11-17 16:17
#69023 #69023
User since
2005-12-17
1615 Artikel
HausmeisterIn
[Homepage]
user image
Hallo nochmal,

zumindest habe ich eine andere Lösung mit CPAN:Storable gefunden... - thx to phaylon =)

Mit nfreeze() und thaw() klappt es sehr gut. Es waere auch nicht besonders
toll gewesen, wenn ich etwas anderes hätte benutzen müssen, da Storable
auch noch die schnellste Lösung ist:

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
use strict;
use warnings;
use Benchmark;
use Data::Dumper;
use YAML;
use JSON;
use XML::Dumper;
use Storable qw(nfreeze thaw);
use Safe;

my $struct = {
  s1 => [qw(v1 v2 v3 v4 v5 v6 v7 v8 v9 v0)],
  s2 => {
     s3 => [qw(v11 v12 v13 v14 v15 v16 v17 v18 v19 v20)],
     s4 => 'v21',
  },
  s5 => [ { s6 => 'v22', s7 => 'v23' }, { s8 => 'v24', s9 => 'v25' } ],
  s0 => 'v26',
};

sub xml_dumper {
  my $dmp = new XML::Dumper;
  my $p2s = $dmp->pl2xml($struct);
  my $s2p = $dmp->xml2pl($p2s);
}

sub json {
  my $json = new JSON;
  my $p2s  = $json->objToJson($struct);
  my $s2p  = $json->jsonToObj($p2s);
}

sub storable {
  my $safe = new Safe;
  $safe->permit(qw(:default require));
  {
     no warnings 'once';
     $Storable::Deparse = 1;
     $Storable::Eval = sub { $safe->reval($_[0]) };
  }
  my $p2s = nfreeze $struct;
  my $s2p = thaw $p2s;
}

sub data_dumper {
  my $p2s = Dumper($struct);
  my $safe = new Safe;
  my $s2p = $safe->reval($p2s);
}

sub yaml {
  my $p2s = Dump($struct);
  my $s2p = Load($p2s);
}

Benchmark::cmpthese(-1,{
  'xml-dumper'  => \&xml_dumper,
  'storable'    => \&storable,
  'data-dumper' => \&data_dumper,
  'yaml'        => \&yaml,
  'json'        => \&json,
});


             Rate        yaml  xml-dumper data-dumper        json    storable
yaml         107/s          --        -74%        -87%        -87%        -98%
xml-dumper   406/s        281%          --        -49%        -52%        -92%
data-dumper  792/s        643%         95%          --         -6%        -84%
json         844/s        691%        108%          6%          --        -83%
storable    5020/s       4606%       1135%        533%        495%          --


Aber ich bin immer noch offen für andere Module! :)
What is a good module? That's hard to say.
What is good code? That's also hard to say.
One man's Thing of Beauty is another's man's Evil Hack.
<< |< 1 2 3 4 >| >> 31 Einträge, 4 Seiten



View all threads created 2006-08-20 07:23.