AC-Yenta

 view release on metacpan or  search on metacpan

lib/AC/Yenta/Crypto.pm  view on Meta::CPAN

    my $me  = shift;
    my $buf = shift;

    my $seqno  = int( time() * 1_000_000 );
    my $nonce  = random_text(48);
    my $key    = $me->_key($seqno, $nonce);
    my $iv     = $me->_iv($key, $seqno, $nonce);

    # pad
    my $pbuf = $buf;
    $pbuf .= "\0" x (16 - length($pbuf) & 0xF) if length($pbuf) & 0xF;

    my $aes    = Crypt::Rijndael->new( $key, Crypt::Rijndael::MODE_CBC );
    $aes->set_iv( $iv );
    my $ct     = $aes->encrypt( $pbuf );
    my $hmac   = hmac_sha256_base64($ct, $key);

    my $eb     = ACPEncrypt->encode( {
        algorithm	=> $ALGORITHM,
        seqno		=> $seqno,
        nonce		=> $nonce,
        hmac		=> $hmac,
        length		=> length($buf),
        ciphertext	=> $ct,
    } );

    debug("encrypted <$seqno,$nonce,$hmac>");

    return $eb;
}

sub decrypt {
    my $me  = shift;

lib/AC/Yenta/Crypto.pm  view on Meta::CPAN

    my $seqno  = $ed->{seqno},
    my $nonce  = $ed->{nonce};
    my $key    = $me->_key($seqno, $nonce);
    my $iv     = $me->_iv($key, $seqno, $nonce);

    my $hmac   = hmac_sha256_base64($ed->{ciphertext}, $key);
    die "cannot decrypt: hmac mismatch\n" unless $hmac eq $ed->{hmac};

    my $aes    = Crypt::Rijndael->new( $key, Crypt::Rijndael::MODE_CBC );
    $aes->set_iv( $iv );
    my $pt     = substr($aes->decrypt( $ed->{ciphertext} ), 0, $ed->{length});

    debug("decrypted <$seqno,$nonce,$hmac>");

    return $pt;
}


sub _key {
    my $me    = shift;
    my $seqno = shift;

lib/AC/Yenta/Kibitz/Status/Client.pm  view on Meta::CPAN

sub start {
    my $me = shift;

    $me->SUPER::start();

    # build request
    my $yp  = AC::Yenta::Protocol->new();
    my $pb  = AC::Yenta::Kibitz::Status::myself();
    my $hdr = $yp->encode_header(
        type		=> 'yenta_status',
        data_length	=> length($pb),
        content_length	=> 0,
        want_reply	=> 1,
        msgid		=> $msgid++,
       );

    # write request
    $me->write( $hdr . $pb );
    $me->timeout_rel($TIMEOUT);
    return $me;
}

lib/AC/Yenta/Kibitz/Status/Server.pm  view on Meta::CPAN

    }

    AC::Yenta::NetMon::update( $io );

    # respond with all known peers
    my $response = AC::Yenta::Kibitz::Status::response();
    my $yp  = AC::Yenta::Protocol->new();

    my $hdr = $yp->encode_header(
        type		=> 'yenta_status',
        data_length	=> length($response),
        content_length  => 0,
        msgid		=> $proto->{msgid},
        is_reply	=> 1,
       );

    debug("sending status reply");
    $io->write_and_shut( $hdr . $response );
}

1;

lib/AC/Yenta/Kibitz/Store/Server.pm  view on Meta::CPAN

    eval {
        $meta = decode_json($meta);
    };
    return 1 if $@;

    if( $meta->{sha1} ){
        my $chk = sha1_base64( $$cont );
        return unless $chk eq $meta->{sha1};
    }
    if( $meta->{size} ){
        my $len = length($$cont);
        return unless $len == $meta->{size};
    }

    return 1;
}

sub _reply_error {
    my $io    = shift;
    my $proto = shift;
    my $code  = shift;

lib/AC/Yenta/Monitor/Client.pm  view on Meta::CPAN

    $me->set_callback('timeout',  \&timeout);
    $me->set_callback('read',     \&read);
    $me->set_callback('shutdown', \&shutdown);

    $me->start();

    # build request
    my $yp  = AC::Yenta::Protocol->new( secret => conf_value('secret') );
    my $hdr = $yp->encode_header(
        type		=> 'heartbeat_request',
        data_length	=> 0,
        content_length	=> 0,
        want_reply	=> 1,
        msgid		=> $msgid++,
       );

    # write request
    $me->write( $hdr );

    $me->timeout_rel($TIMEOUT);

    return $me;

lib/AC/Yenta/Protocol.pm  view on Meta::CPAN


sub read_protocol {
    my $me  = shift;
    my $io  = shift;
    my $evt = shift;

    $io->{rbuffer} .= $evt->{data};

    return _read_http($io, $evt) if $io->{rbuffer} =~ /^GET/;

    if( length($io->{rbuffer}) >= $HDRSIZE && !$io->{proto_header} ){
        # decode header
        eval {
            $io->{proto_header} = $me->decode_header( $io->{rbuffer} );
        };
        if(my $e=$@){
            verbose("cannot decode protocol header: $e");
            $io->run_callback('error', {
                cause	=> 'read',
                error	=> "cannot decode protocol: $e",
            });
            $io->shut();
            return;
        }
    }

    my $p = $io->{proto_header};
    return unless $p; 	# read more

    # do we have everything?
    return unless length($io->{rbuffer}) >= ($p->{auth_length} + $p->{data_length} + $p->{content_length} + $HDRSIZE);

    my $auth    = substr($io->{rbuffer}, $HDRSIZE,  $p->{auth_length});
    my $data    = substr($io->{rbuffer}, $HDRSIZE + $p->{auth_length},  $p->{data_length});
    my $content = substr($io->{rbuffer}, $HDRSIZE + $p->{auth_length} + $p->{data_length}, $p->{content_length});

    # RSN - validate auth

    if( $p->{data_encrypted} && $data ){
        $data = $me->_decrypt_data( $io, $auth, $data );
        return unless $data;
    }

    if( $p->{content_encrypted} && $content ){
        $content = $me->_decrypt_data( $io, $auth, $content );

lib/AC/Yenta/SixtyFour.pm  view on Meta::CPAN

# $Id$

package AC::Yenta::SixtyFour;
use strict;

# export one set of functions as x64_<name>
sub import {
    my $class  = shift;
    my $caller = caller;

    my $l = length(sprintf '%x', -1);
    my $prefix;
    if( $l >= 16 ){
        $prefix = 'native_';
    }else{
        $prefix = 'bigint_';
        require Math::BigInt;
    }

    no strict;
    no warnings;

lib/AC/Yenta/SixtyFour.pm  view on Meta::CPAN


################################################################


sub bigint_number_to_hex {
    my $v = shift;

    if( ref $v ){
        my $h = $v->as_hex();

        # remove leading '0x', and pad to length 16
        $h =~ s/^0x//;
        return ('0' x (16 - length($h))) . $h;

    }else{
        # QQQ?
        return sprintf '%016X', $v;
    }
}

sub bigint_hex_to_number {
    my $v = shift;
    return Math::BigInt->new('0x' . $v);

lib/AC/Yenta/Stats.pm  view on Meta::CPAN

    $f = \&http_file if $url =~ m|^file/|;
    $f ||= \&http_notfound;
    my( $content, $code, $text ) = $f->($url);
    $code ||= 200;
    $text ||= 'OK';

    my $res = "HTTP/1.0 $code $text\r\n"
      . "Server: AC/Yenta\r\n"
      . "Connection: close\r\n"
      . "Content-Type: text/plain; charset=UTF-8\r\n"
      . "Content-Length: " . length($content) . "\r\n"
      . "\r\n"
      . $content ;

    $io->write($res);
    $io->set_callback('write_buffer_empty', \&_done );
}

sub _done {
    my $io = shift;
    $io->shut();

lib/AC/Yenta/Store/Map.pm  view on Meta::CPAN


    # is this the newest version? should we save this data?
    if( !@versions || ($v gt $versions[0]) || $cf->{keepold} ){

        # save file; data is filename
        if( $file ){
            my $r = $me->{fs}->put($data, $file);
            return unless $r;
        }
        # put meta + data
        $db->put($me->{name}, 'meta', $vk, $meta) if length $meta;
        $db->put($me->{name}, 'data', $vk, $data);

        unless( $cf->{keepold} ){
            # unless we are keeping old data, remove previous version
            $deletedata{$versions[0]} = 1 if @versions;
        }
    }

    # add new version to list. newest 1st
    @versions = sort {$b cmp $a} (@versions, $v);

lib/AC/protobuf/auth.pl  view on Meta::CPAN

                    'nonce', 3, undef
                ],
                [
                    Google::ProtocolBuffers::Constants::LABEL_REQUIRED(), 
                    Google::ProtocolBuffers::Constants::TYPE_STRING(), 
                    'hmac', 4, undef
                ],
                [
                    Google::ProtocolBuffers::Constants::LABEL_REQUIRED(), 
                    Google::ProtocolBuffers::Constants::TYPE_INT32(), 
                    'length', 5, undef
                ],
                [
                    Google::ProtocolBuffers::Constants::LABEL_REQUIRED(), 
                    Google::ProtocolBuffers::Constants::TYPE_BYTES(), 
                    'ciphertext', 50, undef
                ],

            ],
            { 'create_accessors' => 1, 'follow_best_practice' => 1,  }
        );

proto/auth.proto  view on Meta::CPAN

        required string         algorithm       = 1;
        // NYI
}

message ACPEncrypt {

        required string         algorithm       = 1;
        required fixed64        seqno           = 2;
        required string         nonce           = 3;
        required string         hmac            = 4;
        required int32          length          = 5;

        required bytes          ciphertext      = 50;
}



( run in 0.552 second using v1.01-cache-2.11-cpan-65fba6d93b7 )