Skip to content

Commit d878d13

Browse files
author
Cocker Koch
committed
Use Puppet-Datatype Sensitive for Passwords
- add Parameter "sensitive" to Function postgresql_password to decide if its Returnvalue should be of Datatype Sensitive - let defined Type postgresql::server::role accept Datatype Sensitive for $password_hash - let defined Type postgresql::server::db accept Datatype Sensitive for $password - let Class postgresql::server accept Datatype Sensitive for $postgres_password - let defined Type postgresql::validate_db_connection accept Sensitive for $database_password
1 parent 09b242a commit d878d13

File tree

10 files changed

+120
-57
lines changed

10 files changed

+120
-57
lines changed

.sync.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
---
22
".gitlab-ci.yml":
33
delete: true
4+
.puppet-lint.rc:
5+
extra_disabled_lint_checks:
6+
- 140chars-check
47
appveyor.yml:
58
delete: true
69

REFERENCE.md

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -863,7 +863,7 @@ The following parameters are available in the `postgresql::server` class:
863863

864864
##### <a name="postgres_password"></a>`postgres_password`
865865

866-
Data type: `Any`
866+
Data type: `Variant[String, Sensitive[String]]`
867867

868868
Sets the password for the postgres user to your specified value. By default, this setting uses the superuser account in the Postgres database, with a user called postgres and no password.
869869

@@ -1646,7 +1646,7 @@ User to create and assign access to the database upon creation. Mandatory.
16461646

16471647
##### <a name="password"></a>`password`
16481648

1649-
Data type: `Any`
1649+
Data type: `Variant[String, Sensitive[String]]`
16501650

16511651
Required Sets the password for the created user.
16521652

@@ -2571,7 +2571,7 @@ Default value: ``true``
25712571

25722572
##### <a name="password_hash"></a>`password_hash`
25732573

2574-
Data type: `Any`
2574+
Data type: `Variant[String, Sensitive[String]]`
25752575

25762576
Sets the hash to use during password creation.
25772577

@@ -2713,7 +2713,7 @@ Create a new schema.
27132713

27142714
#### Examples
27152715

2716-
#####
2716+
#####
27172717

27182718
```puppet
27192719
postgresql::server::schema {'private':
@@ -2944,7 +2944,7 @@ Default value: ``undef``
29442944

29452945
##### <a name="database_password"></a>`database_password`
29462946

2947-
Data type: `Any`
2947+
Data type: `Variant[String, Sensitive[String]]`
29482948

29492949
Specifies the password to connect with.
29502950

@@ -3106,6 +3106,8 @@ The name of the database you are trying to validate a connection with.
31063106

31073107
##### <a name="db_password"></a>`db_password`
31083108

3109+
Data type: `Variant[String, Sensitive[String]]`
3110+
31093111
The password required to access the target PostgreSQL database.
31103112

31113113
##### <a name="db_username"></a>`db_username`
@@ -3319,7 +3321,7 @@ This function pull default values from the `params` class or `globals` class if
33193321

33203322
#### Examples
33213323

3322-
#####
3324+
#####
33233325

33243326
```puppet
33253327
postgresql::default('variable')
@@ -3333,7 +3335,7 @@ Returns: `Any`
33333335

33343336
##### Examples
33353337

3336-
######
3338+
######
33373339

33383340
```puppet
33393341
postgresql::default('variable')
@@ -3369,7 +3371,7 @@ Type: Ruby 4.x API
33693371

33703372
This function returns the postgresql password hash from the clear text username / password
33713373

3372-
#### `postgresql::postgresql_password(Variant[String[1],Integer] $username, Variant[String[1],Integer] $password)`
3374+
#### `postgresql::postgresql_password(Variant[String[1],Integer] $username, Variant[String[1], Sensitive[String[1]], Integer] $password)`
33733375

33743376
The postgresql::postgresql_password function.
33753377

@@ -3387,6 +3389,12 @@ Data type: `Variant[String[1],Integer]`
33873389

33883390
The clear text `password`
33893391

3392+
##### `sensitive`
3393+
3394+
Data type: `Boolean`
3395+
3396+
If the Postgresql-Passwordhash should be of Datatype Sensitive[String]
3397+
33903398
### <a name="postgresql_escape"></a>`postgresql_escape`
33913399

33923400
Type: Ruby 4.x API

lib/puppet/functions/postgresql/postgresql_password.rb

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,25 @@
66
# The clear text `username`
77
# @param password
88
# The clear text `password`
9+
# @param sensitive
10+
# If the Postgresql-Passwordhash should be of Datatype Sensitive[String]
911
#
10-
# @return [String]
12+
# @return
1113
# The postgresql password hash from the clear text username / password.
1214
dispatch :default_impl do
13-
param 'Variant[String[1],Integer]', :username
14-
param 'Variant[String[1],Integer]', :password
15+
required_param 'Variant[String[1], Integer]', :username
16+
required_param 'Variant[String[1], Sensitive[String[1]], Integer]', :password
17+
optional_param 'Boolean', :sensitive
18+
return_type 'Variant[String, Sensitive[String]]'
1519
end
1620

17-
def default_impl(username, password)
18-
'md5' + Digest::MD5.hexdigest(password.to_s + username.to_s)
21+
def default_impl(username, password, sensitive = false)
22+
password = password.unwrap if password.respond_to?(:unwrap)
23+
result_string = 'md5' + Digest::MD5.hexdigest(password.to_s + username.to_s)
24+
if sensitive
25+
Puppet::Pops::Types::PSensitiveType::Sensitive.new(result_string)
26+
else
27+
result_string
28+
end
1929
end
2030
end

manifests/server.pp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@
8383
# @param extra_systemd_config Adds extra config to systemd config file, can for instance be used to add extra openfiles. This can be a multi line string
8484
#
8585
class postgresql::server (
86-
$postgres_password = undef,
86+
Optional[Variant[String[1], Sensitive[String[1]], Integer]] $postgres_password = undef,
8787

8888
$package_name = $postgresql::params::server_package_name,
8989
$package_ensure = $postgresql::params::package_ensure,

manifests/server/db.pp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# @summary Define for conveniently creating a role, database and assigning the correctpermissions.
2-
#
2+
#
33
# @param user User to create and assign access to the database upon creation. Mandatory.
44
# @param password Required Sets the password for the created user.
55
# @param comment Defines a comment to be stored about the database using the PostgreSQL COMMENT command.
@@ -13,7 +13,7 @@
1313
# @param owner Sets a user as the owner of the database.
1414
define postgresql::server::db (
1515
$user,
16-
$password,
16+
Variant[String, Sensitive[String]] $password,
1717
$comment = undef,
1818
$dbname = $title,
1919
$encoding = $postgresql::server::encoding,

manifests/server/default_privileges.pp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@
144144
psql_group => $group,
145145
psql_path => $psql_path,
146146
unless => $unless_cmd,
147-
environment => "PGOPTIONS=--client-min-messages=error"
147+
environment => 'PGOPTIONS=--client-min-messages=error'
148148
}
149149

150150
if($role != undef and defined(Postgresql::Server::Role[$role])) {

manifests/server/passwd.pp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
# @api private
22
class postgresql::server::passwd {
3-
$postgres_password = $postgresql::server::postgres_password
3+
$postgres_password = if $postgresql::server::postgres_password =~ Sensitive {
4+
$postgresql::server::postgres_password.unwrap
5+
} else {
6+
$postgresql::server::postgres_password
7+
}
8+
49
$user = $postgresql::server::user
510
$group = $postgresql::server::group
611
$psql_path = $postgresql::server::psql_path

manifests/server/role.pp

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
# @param module_workdir Specifies working directory under which the psql command should be executed. May need to specify if '/tmp' is on volume mounted with noexec option.
2121
define postgresql::server::role (
2222
$update_password = true,
23-
$password_hash = false,
23+
Variant[Boolean, String, Sensitive[String]] $password_hash = false,
2424
$createdb = false,
2525
$createrole = false,
2626
$db = $postgresql::server::default_database,
@@ -38,6 +38,11 @@
3838
$module_workdir = $postgresql::server::module_workdir,
3939
Enum['present', 'absent'] $ensure = 'present',
4040
) {
41+
$password_hash_unsensitive = if $password_hash =~ Sensitive[String] {
42+
$password_hash.unwrap
43+
} else {
44+
$password_hash
45+
}
4146
#
4247
# Port, order of precedence: $port parameter, $connect_settings[PGPORT], $postgresql::server::port
4348
#
@@ -75,17 +80,17 @@
7580
$createdb_sql = $createdb ? { true => 'CREATEDB', default => 'NOCREATEDB' }
7681
$superuser_sql = $superuser ? { true => 'SUPERUSER', default => 'NOSUPERUSER' }
7782
$replication_sql = $replication ? { true => 'REPLICATION', default => '' }
78-
if ($password_hash != false) {
79-
$password_sql = "ENCRYPTED PASSWORD '${password_hash}'"
83+
if ($password_hash_unsensitive != false) {
84+
$password_sql = "ENCRYPTED PASSWORD '${password_hash_unsensitive}'"
8085
} else {
8186
$password_sql = ''
8287
}
8388

8489
postgresql_psql { "CREATE ROLE ${username} ENCRYPTED PASSWORD ****":
85-
command => Sensitive("CREATE ROLE \"${username}\" ${password_sql} ${login_sql} ${createrole_sql} ${createdb_sql} ${superuser_sql} ${replication_sql} CONNECTION LIMIT ${connection_limit}"),
86-
unless => "SELECT 1 FROM pg_roles WHERE rolname = '${username}'",
87-
require => undef,
88-
sensitive => true,
90+
command => Sensitive("CREATE ROLE \"${username}\" ${password_sql} ${login_sql} ${createrole_sql} ${createdb_sql} ${superuser_sql} ${replication_sql} CONNECTION LIMIT ${connection_limit}"),
91+
unless => "SELECT 1 FROM pg_roles WHERE rolname = '${username}'",
92+
require => undef,
93+
sensitive => true,
8994
}
9095

9196
postgresql_psql { "ALTER ROLE \"${username}\" ${superuser_sql}":
@@ -124,17 +129,17 @@
124129
unless => "SELECT 1 FROM pg_roles WHERE rolname = '${username}' AND rolconnlimit = ${connection_limit}",
125130
}
126131

127-
if $password_hash and $update_password {
128-
if($password_hash =~ /^md5.+/) {
129-
$pwd_hash_sql = $password_hash
132+
if $password_hash_unsensitive and $update_password {
133+
if($password_hash_unsensitive =~ /^md5.+/) {
134+
$pwd_hash_sql = $password_hash_unsensitive
130135
} else {
131-
$pwd_md5 = md5("${password_hash}${username}")
136+
$pwd_md5 = md5("${password_hash_unsensitive}${username}")
132137
$pwd_hash_sql = "md5${pwd_md5}"
133138
}
134139
postgresql_psql { "ALTER ROLE ${username} ENCRYPTED PASSWORD ****":
135-
command => Sensitive("ALTER ROLE \"${username}\" ${password_sql}"),
136-
unless => Sensitive("SELECT 1 FROM pg_shadow WHERE usename = '${username}' AND passwd = '${pwd_hash_sql}'"),
137-
sensitive => true,
140+
command => Sensitive("ALTER ROLE \"${username}\" ${password_sql}"),
141+
unless => Sensitive("SELECT 1 FROM pg_shadow WHERE usename = '${username}' AND passwd = '${pwd_hash_sql}'"),
142+
sensitive => true,
138143
}
139144
}
140145
} else {

manifests/validate_db_connection.pp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# @summary This type validates that a successful postgres connection.
2-
#
2+
#
33
# @note
44
# This validated if the postgres connection can be established
55
# between the node on which this resource is run and a specified postgres
@@ -20,7 +20,7 @@
2020
define postgresql::validate_db_connection (
2121
$database_host = undef,
2222
$database_name = undef,
23-
$database_password = undef,
23+
Optional[Variant[String, Sensitive[String]]] $database_password = undef,
2424
$database_username = undef,
2525
$database_port = undef,
2626
$connect_settings = undef,
@@ -34,6 +34,12 @@
3434

3535
warning('postgresql::validate_db_connection is deprecated, please use postgresql_conn_validator.')
3636

37+
$database_password_unsensitive = if $database_password =~ Sensitive[String] {
38+
$database_password.unwrap
39+
} else {
40+
$database_password
41+
}
42+
3743
$psql_path = $postgresql::params::psql_path
3844
$module_workdir = $postgresql::params::module_workdir
3945
$validcon_script_path = $postgresql::client::validcon_script_path
@@ -55,9 +61,9 @@
5561
undef => "--dbname ${postgresql::params::default_database} ",
5662
default => "--dbname ${database_name} ",
5763
}
58-
$pass_env = $database_password ? {
64+
$pass_env = $database_password_unsensitive ? {
5965
undef => undef,
60-
default => "PGPASSWORD=${database_password}",
66+
default => "PGPASSWORD=${database_password_unsensitive}",
6167
}
6268
$cmd = join([$cmd_init, $cmd_host, $cmd_user, $cmd_port, $cmd_dbname], ' ')
6369
$validate_cmd = "${validcon_script_path} ${sleep} ${tries} '${cmd}'"
@@ -66,8 +72,8 @@
6672
# time it takes to run each psql command.
6773
$timeout = (($sleep + 2) * $tries)
6874

69-
# Combine $database_password and $connect_settings into an array of environment
70-
# variables, ensure $database_password is last, allowing it to override a password
75+
# Combine $database_password_unsensitive and $connect_settings into an array of environment
76+
# variables, ensure $database_password_unsensitive is last, allowing it to override a password
7177
# from the $connect_settings hash
7278
if $connect_settings != undef {
7379
if $pass_env != undef {

spec/unit/defines/server/role_spec.rb

Lines changed: 45 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -20,30 +20,56 @@
2020
'test'
2121
end
2222

23-
let :params do
24-
{
25-
password_hash: 'new-pa$s',
26-
}
27-
end
28-
2923
let :pre_condition do
3024
"class {'postgresql::server':}"
3125
end
3226

33-
it { is_expected.to contain_postgresql__server__role('test') }
34-
it 'has create role for "test" user with password as ****' do
35-
is_expected.to contain_postgresql_psql('CREATE ROLE test ENCRYPTED PASSWORD ****')
36-
.with('command' => 'Sensitive [value redacted]',
37-
'sensitive' => 'true',
38-
'unless' => "SELECT 1 FROM pg_roles WHERE rolname = 'test'",
39-
'port' => '5432')
27+
context 'with Password Datatype String' do
28+
let :params do
29+
{
30+
password_hash: 'new-pa$s',
31+
}
32+
end
33+
34+
it { is_expected.to contain_postgresql__server__role('test') }
35+
it 'has create role for "test" user with password as ****' do
36+
is_expected.to contain_postgresql_psql('CREATE ROLE test ENCRYPTED PASSWORD ****')
37+
.with('command' => 'Sensitive [value redacted]',
38+
'sensitive' => 'true',
39+
'unless' => "SELECT 1 FROM pg_roles WHERE rolname = 'test'",
40+
'port' => '5432')
41+
end
42+
it 'has alter role for "test" user with password as ****' do
43+
is_expected.to contain_postgresql_psql('ALTER ROLE test ENCRYPTED PASSWORD ****')
44+
.with('command' => 'Sensitive [value redacted]',
45+
'sensitive' => 'true',
46+
'unless' => 'Sensitive [value redacted]',
47+
'port' => '5432')
48+
end
4049
end
41-
it 'has alter role for "test" user with password as ****' do
42-
is_expected.to contain_postgresql_psql('ALTER ROLE test ENCRYPTED PASSWORD ****')
43-
.with('command' => 'Sensitive [value redacted]',
44-
'sensitive' => 'true',
45-
'unless' => 'Sensitive [value redacted]',
46-
'port' => '5432')
50+
51+
context 'with Password Datatype Sensitive[String]' do
52+
let :params do
53+
{
54+
password_hash: sensitive('new-pa$s'),
55+
}
56+
end
57+
58+
it { is_expected.to contain_postgresql__server__role('test') }
59+
it 'has create role for "test" user with password as ****' do
60+
is_expected.to contain_postgresql_psql('CREATE ROLE test ENCRYPTED PASSWORD ****')
61+
.with('command' => 'Sensitive [value redacted]',
62+
'sensitive' => 'true',
63+
'unless' => "SELECT 1 FROM pg_roles WHERE rolname = 'test'",
64+
'port' => '5432')
65+
end
66+
it 'has alter role for "test" user with password as ****' do
67+
is_expected.to contain_postgresql_psql('ALTER ROLE test ENCRYPTED PASSWORD ****')
68+
.with('command' => 'Sensitive [value redacted]',
69+
'sensitive' => 'true',
70+
'unless' => 'Sensitive [value redacted]',
71+
'port' => '5432')
72+
end
4773
end
4874

4975
context 'with specific db connection settings - default port' do

0 commit comments

Comments
 (0)