App-Raps2

 view release on metacpan or  search on metacpan

bin/raps2  view on Meta::CPAN

	$xclip_cmd = 'xclip -l 2';
}

my ( $action, @args ) = @ARGV;
my $raps2 = App::Raps2->new(
	cost      => $default_cost,
	pwgen_cmd => $pwgen_cmd,
	xclip_cmd => $xclip_cmd,
);

sub file_must_exist {
	my ( $file, $name ) = @_;

	if ( not defined $file ) {
		say STDERR "No such account: ${name}";
		exit 2;
	}

	return;
}

sub file_must_not_exist {
	my ( $file, $name ) = @_;

	if ( -e $file ) {
		say STDERR "Account already exists: ${name}";
		exit 2;
	}

	return;
}

sub cmd_add {
	my ($name) = @_;

	if ( not $name ) {
		cmd_help( 1, 'add <account>' );
	}

	my $pwfile = data_home('raps2') . "/${name}";

	file_must_not_exist( $pwfile, $name );

	$raps2->get_master_password();

	my $url   = $raps2->ui->read_line('URL');
	my $login = $raps2->ui->read_line('Login');
	my $pass  = $raps2->ui->read_pw( 'Password', 1 );
	my $extra = $raps2->ui->read_multiline('Additional content');

	if ( length($pass) == 0 ) {
		$pass = $raps2->generate_password();

		if ( not $pass ) {
			say STDERR "Password generation failed: ${!}: "
			  . $raps2->conf('pwgen_cmd');
			exit 3;
		}

		if ($paste) {
			$raps2->ui->to_clipboard( $pass, $raps2->conf('xclip_cmd') );
		}
		elsif ( not $no_echo ) {
			$raps2->ui->output( [ 'Generated password', $pass ] );
		}
	}

	$raps2->pw_save(
		file     => $pwfile,
		url      => $url,
		login    => $login,
		password => $pass,
		extra    => $extra,
	);

	return;
}

sub cmd_dump {
	my ($name) = @_;

	if ( not $name ) {
		cmd_help( 1, 'dump <account>' );
	}

	my $pwfile = data_files("raps2/${name}");

	file_must_exist( $pwfile, $name );

	$raps2->get_master_password();

	my $key = $raps2->pw_load( file => $pwfile );

	$raps2->ui->output(
		[ 'URL',      $key->{url} ],
		[ 'Login',    $key->{login} ],
		[ 'Password', $key->{password} ],
	);
	if ( $key->{extra} ) {
		print $key->{extra};
	}

	return;
}

sub cmd_dump_all {
	my @files = read_dir( data_home('raps2') );

	$raps2->get_master_password();

	for my $file (@files) {
		my $key = $raps2->pw_load( file => data_files("raps2/${file}") );

		$raps2->ui->output(
			[ 'Key',      $file ],
			[ 'URL',      $key->{url} ],
			[ 'Login',    $key->{login} ],
			[ 'Password', $key->{password} ],
		);
		if ( $key->{extra} ) {
			print $key->{extra};

bin/raps2  view on Meta::CPAN

	}

	return;
}

sub cmd_edit {
	my ($name) = @_;

	if ( not $name ) {
		cmd_help( 1, 'edit <account>' );
	}

	my $pwfile = data_files("raps2/${name}");

	file_must_exist( $pwfile, $name );

	$raps2->get_master_password();

	my $key = $raps2->pw_load( file => $pwfile );

	my $salt     = $key->{salt};
	my $cost     = $key->{cost};
	my $url      = $raps2->ui->read_line( 'URL', $key->{url} );
	my $login    = $raps2->ui->read_line( 'Login', $key->{login} );
	my $pass     = $key->{password};
	my $new_pass = $raps2->ui->read_pw( 'New password (empty to keep old)', 1 );
	my $extra    = $key->{extra} // q{};

	if ( length($new_pass) ) {
		$pass = $new_pass;
	}

	$raps2->pw_save(
		file     => $pwfile,
		salt     => $salt,
		cost     => $cost,
		url      => $url,
		login    => $login,
		password => $pass,
		extra    => $extra,
	);

	return;
}

sub cmd_get {
	my ($name) = @_;

	if ( not $name ) {
		cmd_help( 1, 'get <account>' );
	}

	my $pwfile = data_files("raps2/${name}");

	file_must_exist( $pwfile, $name );

	$raps2->get_master_password();

	my $key = $raps2->pw_load( file => $pwfile );

	$raps2->ui->to_clipboard( $key->{password}, $raps2->conf('xclip_cmd') )
	  or die("Could not place password in clipboard: ${!}\n");

	if ( $key->{extra} ) {
		print $key->{extra};
	}

	return;
}

sub cmd_help {
	my ( $exit_status, $subcmd ) = @_;

	$subcmd //= 'add|get|dump|... [account]';

	say "Usage: raps2 ${subcmd}";
	say 'See also: "man raps2"';

	exit $exit_status;
}

sub cmd_info {
	my ($name) = @_;

	if ( not $name ) {
		cmd_help( 1, 'info <account>' );
	}

	my $pwfile = data_files("raps2/${name}");

	file_must_exist( $pwfile, $name );

	my $key = $raps2->pw_load_info( file => $pwfile );
	$raps2->ui->output( [ 'URL', $key->{url} ], [ 'Login', $key->{login} ], );

	return;
}

sub cmd_list {
	my @files = read_dir( data_home('raps2') );

	for my $file ( sort @files ) {
		my $key = $raps2->pw_load_info( name => $file );
		$raps2->ui->list(
			[ 'Account', $file ],
			[ 'Login',   $key->{login} ],
			[ 'URL',     $key->{url} ],
		);
	}

	return;
}

sub cmd_remove {
	my ($name) = @_;

	if ( not $name ) {
		cmd_help( 1, 'del <account>' );
	}

	my $pwfile = data_files("raps2/${name}");

bin/raps2  view on Meta::CPAN


=item B<-P>, B<--paste>

When using the pwgen functionality of B<raps2 add>, do not print the generated
password on stdout.  Place it in the X Clipboard instead.

Note that it can only be pasted once, unless B<-x> or B<-C> is used.

=item B<-p>, B<--pwgen-cmd> I<command>

When the user does not enter a password in B<raps2 add>, it will execute
I<command> to create one. The first line of output is taken as password.
If the output contains spaces, anything after the first space (plus the space
itself) is discarded.

Default: pwgen -s 23 1

=item B<-V>, B<--version>

Show version information.

=item B<-x>, B<--xclip-cmd> I<command>

Command to run for B<raps2 get>.  The password will be available on
I<command>'s stdin.

Default: xclip -l 1

=back

=head1 EXIT STATUS

zero on success, non-zero otherwise.

=head1 CONFIGURATION

raps2 saves the master password hash in F<~/.config/raps2/password>.

The configuration (key setup cost and pwgen command) is stored in
F<~/.config/raps2/defaults> in an INI-like format.

Additional encrypted passwords are stored in F<~/.local/share/raps2/>.

These directories can be changed by setting the B<XDG_CONFIG_HOME> and
B<XDG_DATA_HOME> environment variables.

The following settings are available in F<~/.config/raps2/defaults>:

=over

=item B<cost> = 12

Default key setup cost.  See the B<-c> option.

=item B<pwgen_cmd> = pwgen -s 23 1

Command used to generate passwords.  See the B<-p> option.

=item B<xclip_cmd> = xclip -l 1

Command used to place passwords in the clipboard.  See the B<-x> option.

=back

Note that commandline arguments always override options set in the
configuration file.

=head1 DEPENDENCIES

=over

=item * Config::Tiny

=item * Crypt::CBC

=item * Crypt::Eksblowfish

=item * File::BaseDir

=item * File::Path (usually included with perl core)

=item * File::Slurp

=item * pwgen (if you want C<< raps2 add >> to generate passwords)

=item * xclip (for C<< raps2 get >>)

=back

=head1 BUGS AND LIMITATIONS

This is alpha software, the store format may change without further notice.
Backwards-compatibility is not guaranteed.

When running for the first time, raps2 will ask for the master passphrase
three times. Two would be better.

=head1 AUTHOR

Copyright (C) 2011-2015 by Daniel Friesel E<lt>derf@finalrewind.orgE<gt>

=head1 LICENSE

  0. You just DO WHAT THE FUCK YOU WANT TO.



( run in 1.306 second using v1.01-cache-2.11-cpan-2398b32b56e )