From aefe71e8ed84873c543487d46c05af75fc7233eb Mon Sep 17 00:00:00 2001 From: CoolTux Date: Wed, 21 Apr 2021 07:52:34 +0000 Subject: [PATCH] lib/FHEM/Core/Password/Utils.pm: new modul for developer to save passwords or passphrase in fhem keystore git-svn-id: https://svn.fhem.de/fhem/trunk@24295 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/CHANGED | 2 + fhem/lib/FHEM/Core/Password/Utils.pm | 247 +++++++++++++++++++++++++++ 2 files changed, 249 insertions(+) create mode 100644 fhem/lib/FHEM/Core/Password/Utils.pm diff --git a/fhem/CHANGED b/fhem/CHANGED index e0ecb2563..8d1f0fc22 100644 --- a/fhem/CHANGED +++ b/fhem/CHANGED @@ -1,5 +1,7 @@ # Add changes at the top of the list. Keep it in ASCII, and 80-char wide. # Do not insert empty lines here, update check depends on it. + - new: lib/FHEM/Core/Password/Utils.pm: new modul for developer to save + passwords or passphrase in fhem keystore - bugfix: 98_WeekdayTimer: don't enable disabled WDT in group par. setting - feature: 49_IPCAM: attrs unknownFormatRetryCount, unknownFormatRetryDelay and handleAnyXmlAsSvg diff --git a/fhem/lib/FHEM/Core/Password/Utils.pm b/fhem/lib/FHEM/Core/Password/Utils.pm new file mode 100644 index 000000000..c2eadfe81 --- /dev/null +++ b/fhem/lib/FHEM/Core/Password/Utils.pm @@ -0,0 +1,247 @@ +############################################################################### +# +# Developed with Kate +# +# (c) 2021 Copyright: Marko Oldenburg (fhemdevelopment at cooltux dot net) +# All rights reserved +# +# This script is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# any later version. +# +# The GNU General Public License can be found at +# http://www.gnu.org/copyleft/gpl.html. +# A copy is found in the textfile GPL.txt and important notices to the license +# from the author is found in LICENSE.txt distributed with these scripts. +# +# This script is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# +# $Id$ +# +############################################################################### + +package FHEM::Core::Password::Utils; + +use 5.008; + +use strict; +use warnings; + + +### eigene Funktionen exportieren +require Exporter; +our @ISA = qw(Exporter); +our @EXPORT_OK = qw( + new + setStorePassword + setDeletePassword + getReadPassword + setRename +); +our %EXPORT_TAGS = ( + ALL => [ + qw( + new + setStorePassword + setDeletePassword + getReadPassword + setRename + ) + ], +); + + +sub new { + my $class = shift; + my $self = { + name => undef, + }; + + bless $self, $class; + return $self; +} + +sub setStorePassword { + my $self = shift; + my $name = shift; + my $password = shift // return(undef,q{no password given}); + + my $index = $::defs{$name}->{TYPE} . '_' . $name . '_passkey'; + my ($x,$y) = ::gettimeofday(); + my $salt = substr(sprintf("%08X", rand($y)*rand($x)),0,8); + my $key = ::getUniqueId() . $index . $salt; + my $enc_pwd = ''; + + if ( eval q{use Digest::SHA;1} ) { + + $key = Digest::SHA::sha256_hex( unpack "H*", $key ); + $key .= Digest::SHA::sha256_hex($key); + } + + for my $char ( split //, $password ) { + + my $encode = chop($key); + $enc_pwd .= sprintf( "%.2x", ord($char) ^ ord($encode) ); + $key = $encode . $key; + } + + my $err; + $err = ::setKeyValue( $index, $salt . $enc_pwd ); + + return(undef,$err) + if ( defined($err) ); + + return(1); +} + +sub setDeletePassword { + my $self = shift; + my $name = shift; + + my $err; + $err = ::setKeyValue( $::defs{$name}->{TYPE} . '_' . $name . '_passkey', undef ); + + return(undef,$err) + if ( defined($err) ); + + return(1); +} + +sub getReadPassword { + my $self = shift; + my $name = shift; + + my $index = $::defs{$name}->{TYPE} . '_' . $name . '_passkey'; + my ( $password, $err, $salt ); + + ::Log3($name, 4, qq{password Keystore handle for Device ($name) - Read password from file}); + + ( $err, $password ) = ::getKeyValue($index); + + if ( defined($err) ) { + + ::Log3($name, 1, +qq{password Keystore handle for Device ($name) - unable to read password from file: $err}); + + return undef; + } + + if ( defined($password) + and $password =~ m{\A(.{8})(.*)\z}xms ) + { + $salt = $1; + $password = $2; + + my $key = ::getUniqueId() . $index . $salt; + + if ( eval q{use Digest::SHA;1} ) { + + $key = Digest::SHA::sha256_hex( unpack "H*", $key ); + $key .= Digest::SHA::sha256_hex($key); + } + + my $dec_pwd = ''; + + for my $char ( map { pack( 'C', hex($_) ) } ( $password =~ /(..)/g ) ) { + + my $decode = chop($key); + $dec_pwd .= chr( ord($char) ^ ord($decode) ); + $key = $decode . $key; + } + + return $dec_pwd; + } + else { + + ::Log3($name, 1, qq{password Keystore handle for Device ($name) - No password in file}); + return undef; + } +} + +sub setRename { + my $self = shift; + my $newname = shift; + my $oldname = shift; + + my ($resp,$err); + + ($resp,$err) = $self->setStorePassword($newname,$self->getReadPassword($oldname)); # set new password value + return(0,$err) + if ( !defined($resp) + and defined($err) + ); + + ($resp,$err) = $self->setDeletePassword($oldname); # remove old password value + return(0,$err) + if ( !defined($resp) + and defined($err) + ); + + return(1); +} + +1; + + +__END__ + +=head1 NAME + +FHEM::Core::Password::Utils - FHEM extension for password handling + +=head1 VERSION + +This document describes FHEM::Core::Password::Utils version 0.3 + +=head1 CONSTRUCTOR + +FHEM::Core::Password::Utils->new(); + +=head1 SYNOPSIS + + use FHEM::Core::Password::Utils qw(:ALL); + our $passwd = FHEM::Core::Password::Utils->new(); + + you can also save the password object in the instance hash + our $hash->{helper}->{passwdobj} = FHEM::Core::Password::Utils->new(); + +=head1 DESCRIPTION + +Store new Password +$hash->{helper}->{passwdobj}->setStorePassword('PASSWORD'); + +Read Password +$hash->{helper}->{passwdobj}->getReadPassword(); + + + + +=head1 EXPORT + +The following functions are exported by this module: +C,C, C, C + +=over 4 + +=back + +=head1 OBJECTS + +=head1 NOTES + +=head1 BUGS AND LIMITATIONS + +=head1 AUTHOR + +Marko Oldenburg Efhemdevelopment AT cooltux DOT netE + +=head1 LICENSE + +FHEM::Core::Password::Utils is released under the same license as FHEM. + +=cut