Crypt-HSXKPasswd

 view release on metacpan or  search on metacpan

bin/hsxkpasswd  view on Meta::CPAN

        exit 0;
    },
    'test-rcfile=s' => sub{
        my ($opt_name, $val) = @_;
        unless(-f $val){
            byeee("file $val does not exist");
        }
        open my $RCFILE_FH, '<', $val or byee("failed to read file $val with error:\n* $OS_ERROR");
        my $json_string = do{local $/ = undef; <$RCFILE_FH>};
        close $RCFILE_FH;
        my $rcdata;
        eval{
            $rcdata = decode_json($json_string);
            1; # explicit evaluation
        }or do{
            byeee("failed to parse the hsxkpasswdrc file's content as JSON:\n* source file: $val\n* parse error: $EVAL_ERROR");
        };
        say 'Validing the converted datatsructure from the hsxkpasswdrc file ...';
        my $is_valid = RCFileData->check($rcdata);
        if($is_valid){
            say '** hsxkpasswdrc data OK **';
        }else{
            say '** hsxkpasswdrc data INVALID **';
            say RCFileData->get_message($rcdata);
            exit 1;
        }
        exit 0;
    },
    #
    # -- the delayed 'do and exit' options --
    #
    'list-presets|l' => sub{
        my ($opt_name, $val) = @_;
        $cmd_args{do_list_presets} = 1;

bin/hsxkpasswd  view on Meta::CPAN

            byeee("failed to parse --rng-pkg-args as JSON with error:\n* $EVAL_ERROR");
        };
        unless(ArrayRef->check($args)){
            byeee('--rng-pkg-args did not specify JSON representing an array');
        }
        $cmd_args{'rng-pkg-args'} = $args;
    },
    'rcfile=s' => sub{
        my ($opt_name, $val) = @_;
        if($val eq 'NONE'){
            $cmd_args{no_rcdata} = 1;
        }else{
            $cmd_args{rcdata} = load_rcfile($val);
        }
    },
    'verbose' => \$verbose,
    'warn|w=s' => sub{
        my ($opt_name, $val) = @_;
        unless(EntropyWarningLevel->check($val)){
            byeee('invalid entropy warning level: '.EntropyWarningLevel->get_message($val));
        }
        $cmd_args{warn} = uc $val; # make sure it's upper case
    },

bin/hsxkpasswd  view on Meta::CPAN

}

#
# === Try load an hsxkpasswdrc file if possible ================================#
#

# try determine the user's home dir and .hsxkpasswdrc file path
my @home_dir = File::Spec->splitdir(File::HomeDir->my_home());
my $dot_hsxkpasswdrc_path = File::Spec->catfile(@home_dir, '.hsxkpasswdrc');

# start with blank rcdata
my $rcdata = {};

# unless we're skipping rcdata completely, try from the args, then from ~/hsxkpasswdrc
if($cmd_args{no_rcdata}){
    note('loading of hsxkpasswdrc files disabled with --rcfile=NONE');
}else{
    if($cmd_args{rcdata}){
        $rcdata = $cmd_args{rcdata};
        note('using hsxkpasswdrc file from --rcfile option');
    }elsif(-f $dot_hsxkpasswdrc_path){
        $rcdata = load_rcfile($dot_hsxkpasswdrc_path);
        note("using hsxkpasswdrc file $dot_hsxkpasswdrc_path");
    }else{
        note('no hsxkpasswdrc file loaded');
    }
}

#
# === List presets and exit if --list-presets =================================#
#
if($cmd_args{do_list_presets}){
    # merge the presets into a single array
    my %preset_lookup = ();
    my %standard_preset_lookup = ();
    my %custom_preset_lookup = ();
    foreach my $preset (Crypt::HSXKPasswd->defined_presets()){
        $preset_lookup{$preset} = 1;
        $standard_preset_lookup{$preset} = 1;
    }
    if($rcdata->{custom_presets}){
        foreach my $preset (keys %{$rcdata->{custom_presets}}){
            $preset_lookup{$preset} = 1;
            $custom_preset_lookup{$preset} = 1;
        }
    }
    
    # if there are custom presets, print out the detail if in verbose mode
    if($verbose && $rcdata->{custom_presets}){
        note('custom presets (from hsxkpasswdrc file): '.(join q{, }, keys %custom_preset_lookup));
        my @unoverriden_standard_presets = ();
        my @overridden_standard_presets = ();
        foreach my $preset (sort keys %standard_preset_lookup){
            if($custom_preset_lookup{$preset}){
                push @overridden_standard_presets, $preset;
            }else{
                push @unoverriden_standard_presets, $preset;
            }
        }

bin/hsxkpasswd  view on Meta::CPAN

    # exit with success
    exit 0;
}

#
# === Set the Warning Level (if specified) ====================================#
#
if($cmd_args{warn}){
    Crypt::HSXKPasswd->module_config('ENTROPY_WARNINGS', $cmd_args{warn});
    note('using entropy warning level specified with --warn option');
}elsif($rcdata->{default_entropy_warnings}){
    Crypt::HSXKPasswd->module_config('ENTROPY_WARNINGS', $rcdata->{default_entropy_warnings});
    note('using entropy warning level specified in hsxkpasswdrc file');
}else{
    note('no custom entropy warning level set');
}

#
# === Assemble the options for the HSXKPasswd constructor =====================#
#

my %hsxkpwd_args = ();

# deal with the config - first try a directly specified config, then a preset,
# then fall back to the default config
if($cmd_args{config}){
    $hsxkpwd_args{config} = $cmd_args{config};
    note('using config from file specified with --config-file option');
}elsif($cmd_args{preset}){
    # if there is a matching custom preset, use it to generate a config,
    # otherwise treat the config as a standard config
    if($rcdata->{custom_presets} && $rcdata->{custom_presets}->{$cmd_args{preset}}){
        # we are a custom preset
        my $config = $rcdata->{custom_presets}->{$cmd_args{preset}}->{config};
        
        # apply any overrides if needed
        if($cmd_args{preset_overrides}){
            # save the keys into the config
            foreach my $key (keys %{$cmd_args{preset_overrides}}){
                $config->{$key} = $cmd_args{preset_overrides}->{$key};
            }
            # validate the resulting config
            unless(Config->check($config)){
                byeee('the custom preset combined with the specified overrides produces an invalid config: '.Config->get_message($config));

bin/hsxkpasswd  view on Meta::CPAN

        unless(PresetName->check($cmd_args{preset})){
            byeee("no preset exists with the name '$cmd_args{preset}' (you can see all defined presets with: hsxkpasswd --list-presets)");
        }
        $hsxkpwd_args{preset} = $cmd_args{preset};
        if($cmd_args{preset_overrides}){
            $hsxkpwd_args{preset_overrides} = $cmd_args{preset_overrides};
        }
        note(qq{using standard preset '$cmd_args{preset}'});
    }
}else{
    # if the preset DEFUALT is ovrridden by the rcdata, us it
    if($rcdata->{custom_presets} && $rcdata->{custom_presets}->{'DEFAULT'}){
        $hsxkpwd_args{config} = $rcdata->{custom_presets}->{'DEFAULT'}->{config};
        note('using custom default config from hsxkpasswdrc file');
    }else{
        note('using standard default config');
    }
}

# deal with the dictionary - the commandline takes precedence, then the rc file
if($cmd_args{'dict-file'}){
    $hsxkpwd_args{dictionary_file} = $cmd_args{'dict-file'};
    note('using dictionary file from --dict-file option');
}elsif($cmd_args{'dict-pkg'}){
    $hsxkpwd_args{dictionary} = load_dictionary(
        $cmd_args{'dict-pkg'},
        $cmd_args{'dict-pkg-args'} || [],
    );
    note('using dictionary package from --dict-pkg option');
}elsif($rcdata->{default_dictionary}){
    if($rcdata->{default_dictionary}->{file}){
        $hsxkpwd_args{dictionary_file} = $rcdata->{default_dictionary}->{file};
        note('using dictionary file from hsxkpasswdrc file');
    }elsif($rcdata->{default_dictionary}->{package}){
        $hsxkpwd_args{dictionary} = load_dictionary(
            $rcdata->{default_dictionary}->{package},
            $rcdata->{default_dictionary}->{package_constructor_args} || [],
        );
        note('using dictionary package from hsxkpasswdrc file');
    }else{
        # this should be impossible if the rcfile validation is working!
        note('using default word source');
    }
}else{
    note('using default word source');
}

# deal wit the rng - the commandline takes precedence, then the rc file
if($cmd_args{'rng-pkg'}){
    $hsxkpwd_args{rng} = load_rng(
        $cmd_args{'rng-pkg'},
        $cmd_args{'rng-pkg-args'} || [],
    );
    note('using rng package from --rng-pkg option');
}elsif($rcdata->{default_rng}){
    $hsxkpwd_args{rng} = load_rng(
        $rcdata->{default_rng}->{package},
        $rcdata->{default_rng}->{package_constructor_args} || [],
    );
    note('using rng package from hsxkpasswdrc file');
}else{
    note('using default rng');
}

#
# === Generate the Password(s) ================================================#
#

bin/hsxkpasswd  view on Meta::CPAN

    unless(-f $rcfile_path){
        byeee("file $rcfile_path does not exist");
    }
    
    # try slurp the file
    open my $RCFILE_FH, '<', $rcfile_path or byee("failed to read file $rcfile_path with error:\n* $OS_ERROR");
    my $json_string = do{local $/ = undef; <$RCFILE_FH>};
    close $RCFILE_FH;
    
    # try parse the file to JSON
    my $loaded_rcdata = {};
    eval{
        $loaded_rcdata = decode_json($json_string);
        1; # explicit evaluation
    }or do{
        byeee("failed to parse JSON string from file $rcfile_path with error:\n* $EVAL_ERROR");
    };
    
    # validate the data structure represnted by the JSON
    unless(RCFileData->check($loaded_rcdata)){
        byeee("invalid hsxkpasswdrc data from file $rcfile_path:\n* ".RCFileData->get_message($loaded_rcdata));
    }
    
    # return the data
    return $loaded_rcdata;
}

#####-SUB-######################################################################
# Type       : SUBROUTINE
# Purpose    : Load a dictionary object form a package name
# Returns    : An object of a class that extends Crypt::HSXKPasswd::Dictionary
# Arguments  : 1) the Perl package name as a string
#              2) a reference to an array
# Throws     : NOTHING - exists the script if there is a problem
# Notes      : Exits the script with a sane error message via byeee() on error.



( run in 0.600 second using v1.01-cache-2.11-cpan-454fe037f31 )