tis-windows-password-policy

15
Define the local Windows password policy.
409 downloads
Download
See build result See VirusTotal scan
tis-windows-password-policy icon
  • package : tis-windows-password-policy
  • name : Windows Password Policy
  • version : 15
  • categories : Security
  • maintainer : WAPT Team,Tranquil IT, Kévin Guérineau
  • editor : Microsoft
  • licence :
  • locale :
  • target_os : windows
  • impacted_process :
  • architecture : all
  • signature_date : 2024-09-11 10:37
  • size : 6.96 Ko
package           : tis-windows-password-policy
version           : 15
architecture      : all
section           : base
priority          : optional
name              : Windows Password Policy
categories        : Security
maintainer        : WAPT Team,Tranquil IT, Kévin Guérineau
description       : Define the local Windows password policy.
depends           : 
conflicts         : 
maturity          : PROD
locale            : 
target_os         : windows
min_wapt_version  : 2.3
sources           : 
installed_size    : 
impacted_process  : 
description_fr    : Définir la politique locale de mots de passe Windows.
description_pl    : Definiowanie lokalnych zasad haseł systemu Windows.
description_de    : Definieren Sie die lokale Windows-Kennwortrichtlinie.
description_es    : Definir la política local de contraseñas de Windows.
description_pt    : Definir a política de palavra-passe local do Windows.
description_it    : Definire il criterio delle password locali di Windows.
description_nl    : Definieer het lokale Windows wachtwoordbeleid.
description_ru    : Определите локальную политику паролей Windows.
audit_schedule    : 
editor            : Microsoft
keywords          : 
licence           : 
homepage          : 
package_uuid      : 3d6a7ada-5846-4562-9e0a-3af3feae7705
valid_from        : 
valid_until       : 
forced_install_on : 
changelog         : 
min_os_version    : 
max_os_version    : 
icon_sha256sum    : 9420721210f5d9c50c9e35c9fdbf0a088b30e165df8311c5f2176ce60e122475
signer            : Tranquil IT
signer_fingerprint: 8c5127a75392be9cc9afd0dbae1222a673072c308c14d88ab246e23832e8c6bb
signature_date    : 2024-09-11T10:37:21.000000
signed_attributes : package,version,architecture,section,priority,name,categories,maintainer,description,depends,conflicts,maturity,locale,target_os,min_wapt_version,sources,installed_size,impacted_process,description_fr,description_pl,description_de,description_es,description_pt,description_it,description_nl,description_ru,audit_schedule,editor,keywords,licence,homepage,package_uuid,valid_from,valid_until,forced_install_on,changelog,min_os_version,max_os_version,icon_sha256sum,signer,signer_fingerprint,signature_date,signed_attributes
signature         : fZyPWD8FFHmiOH2VQgp5mtNfNpZ1CQP5zpTepEZX25yRSN1LqeoAK9PNKXaUYDJVt86MmFve51vcjcsuKydBNaDFYXCiSKaxZc8hOn9fmuX4wZVTzy/2f2RHPkcxqHqfQgFmo1MEvm0+DFmg7ZkdBEddapz7AR5/HGugRo5ZDQiKLhf/iP10m1VKJPOSgyOM9G5ZTje2e04VEkgN4SC1ZdYLf3Q67bTSuRY5rILrPZDR5edForXAELPCclJCt6SdcZRpM2W/ibaF+IlHz6F3/V0TYEtxXC8fdR1sJrZAvN4fyl7t83oHnXxv7gp4bUgc4w472nUcqMub1DSac9FVgg==
# -*- coding: utf-8 -*-
from setuphelpers import *
import codecs

# Documentation : https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-xp/bb490698(v=technet.10)?redirectedfrom=MSDN

forcelogoff = "no"
minpwlen = 14
maxpwage = 365
minpwage = 1
uniquepw = 24
lockout_threshold = 5
lockout_duration = 15
reset_lockout_count = 15
set_complexity = True
clear_store_pw = False
admin_account_lockout = True


def decode_file(src_file:None,dest_file:None):

    encoded_text = open(src_file, 'rb').read()     #you should read in binary mode to get the BOM correctly
    bom = codecs.BOM_UTF16_LE                               #print dir(codecs) for other encodings
    assert encoded_text.startswith(bom)                     #make sure the encoding is what you expect, otherwise you'll get wrong data
    encoded_text = encoded_text[len(bom):]                  #strip away the BOM
    decoded_text = encoded_text.decode('utf-16le')

    f = open(dest_file, 'wb')
    f.write(decoded_text.encode('utf-8'))
    f.close()


def encode_file(src_file,dest_file):
    encoded_text = open(src_file, 'rb').read()     #you should read in binary mode to get the BOM correctly
    decoded_text = encoded_text.decode('utf-8')

    f = open(dest_file, 'wb')
    f.write(decoded_text.encode('utf-16le'))
    f.close()


def install():
    print(f"Set local password policy")
    run(f"net accounts /forcelogoff:{forcelogoff} /minpwlen:{minpwlen} /maxpwage:{maxpwage} /minpwage:{minpwage} /uniquepw:{uniquepw} \
        /lockoutthreshold:{lockout_threshold} /lockoutwindow:{reset_lockout_count} /lockoutduration:{lockout_duration}")

    run(r'C:\Windows\system32\secedit.exe /export /cfg secconfig.ini /areas SECURITYPOLICY')

    decoded_file = "decoded_secconfig.ini"
    decode_file("secconfig.ini", decoded_file)

    print('Set complexity password')
    if set_complexity:
        if inifile_hasoption(decoded_file,"System Access","PasswordComplexity"):
            if inifile_readstring(decoded_file,"System Access","PasswordComplexity") == "0":
                inifile_writestring(decoded_file,"System Access","PasswordComplexity", "1")
    if not clear_store_pw:
        if inifile_hasoption(decoded_file,"System Access","ClearTextPassword"):
            if inifile_readstring(decoded_file,"System Access","ClearTextPassword") == "1":
                inifile_writestring(decoded_file,"System Access","ClearTextPassword","0")
    if admin_account_lockout:
        if inifile_hasoption(decoded_file,"System Access","AllowAdministratorLockout"):
            if inifile_readstring(decoded_file,"System Access","AllowAdministratorLockout") == "0":
                inifile_writestring(decoded_file,"System Access","AllowAdministratorLockout","1")

    encoded_file = "encoded_secconfig.ini"
    encode_file(decoded_file, encoded_file)

    run(rf'C:\Windows\system32\secedit.exe /import /cfg {encoded_file} /overwrite /areas SECURITYPOLICY /db wapt_secconfig /quiet')
    run(r'C:\Windows\system32\secedit.exe /configure /db wapt_secconfig /overwrite /areas SECURITYPOLICY /quiet')


def uninstall():

    uninstall_dir = makepath('C:','Windows','Temp','secedit_dir')
    mkdirs(uninstall_dir)

    run("net accounts /forcelogoff:no /minpwlen:0 /maxpwage:UNLIMITED /minpwage:0 /uniquepw:0 \
        /lockoutthreshold:0 /lockoutwindow:30 /lockoutduration:30")

    run(r'C:\Windows\system32\secedit.exe /export /cfg C:\Windows\Temp\secconfig.ini /areas SECURITYPOLICY')

    decoded_file = makepath(uninstall_dir,"decoded_secconfig.ini")
    decode_file("C:\Windows\Temp\secconfig.ini",decoded_file)

    print('Unset complexity password')
    inifile_writestring(decoded_file,"System Access","PasswordComplexity", "0")
    inifile_writestring(decoded_file,"System Access","ClearTextPassword","0")
    inifile_writestring(decoded_file,"System Access","AllowAdministratorLockout","1")

    encoded_file = makepath(uninstall_dir,'encode_decoded_secconfig.ini')
    encode_file(decoded_file, encoded_file)

    run(rf'C:\Windows\system32\secedit.exe /import /cfg {encoded_file} /overwrite /areas SECURITYPOLICY /db wapt_secconfig /quiet')
    run(r'C:\Windows\system32\secedit.exe /configure /db wapt_secconfig /overwrite /areas SECURITYPOLICY /quiet')

    remove_tree(uninstall_dir)


def audit():

    audit_dir = makepath('C:','Windows','Temp','secconfig_audit')
    mkdirs(audit_dir)
    audit_file = makepath(audit_dir,"secconfig.ini")

    run(rf'C:\Windows\system32\secedit.exe /export /cfg {audit_file} /areas SECURITYPOLICY')

    decoded_file = makepath(audit_dir,'decoded_secconfig.ini')
    decode_file(audit_file, decoded_file)

    error = False
    params = {"ForceLogoffWhenHourExpire ":forcelogoff},{'MinimumPasswordAge':minpwage},{'MaximumPasswordAge':maxpwage},{'MinimumPasswordLength':minpwlen}, \
        {"PasswordHistorySize":uniquepw},{"LockoutBadCount":lockout_threshold},{"LockoutDuration":lockout_duration},{"ResetLockoutCount":reset_lockout_count},  \
        {'PasswordComplexity':set_complexity},{"ClearTextPassword":clear_store_pw},{"AllowAdministratorLockout":admin_account_lockout}
    for option in params:
        for i in option:
            if inifile_hasoption(decoded_file,"System Access",i):
                if inifile_readstring(decoded_file,"System Access",i) == str(option[i]):
                    print(f"{i} is in correct value : {option[i]}")
                elif str(option[i]) == "True":
                    if inifile_readstring(decoded_file,"System Access",i) == "1":
                        print(f"{i} is in correct value : {option[i]}")
                    else:
                        print(f'{i} isn\'t in correct value : {inifile_readstring(decoded_file,"System Access",i)} expected {option[i]}')
                        error = True
                elif str(option[i]) == "False":
                    if inifile_readstring(decoded_file,"System Access",i) == "0":
                        print(f"{i} is in correct value : {option[i]}")
                    else:
                        print(f'{i} isn\'t in correct value : {inifile_readstring(decoded_file,"System Access",i)} expected {option[i]}')
                        error = True
                else:
                    print(f'{i} isn\'t in correct value : {inifile_readstring(decoded_file,"System Access",i)} expected {option[i]}')
                    error = True

    remove_tree(audit_dir)

    if error:
        return "ERROR"
    else:
        return "OK"
# -*- coding: utf-8 -*-
from setuphelpers import *

def update_package():
    commit_count = params.get("commit_count",0)

    control.version = commit_count
    control.save_control_to_wapt()
38d056ab130f7bf7c481c12636a4e9959de36561d3dfcbe54c6e3571bc0c1dc3 : WAPT/certificate.crt
b6f4a8f5fe301c71ac2d78776ec7ba4eb06dbf74ac8bcf95e1d64a55add03547 : WAPT/control
9420721210f5d9c50c9e35c9fdbf0a088b30e165df8311c5f2176ce60e122475 : WAPT/icon.png
 : __pycache__
6c0a9d05d25f066551d9b1912b0d79e365315b725c58fe7961855b1fa77f9e19 : luti.json
c4c97410af55d70039b697f0623da0a56a69e307bd39b9d1a5addd76f9abd70d : setup.py
0506431355ece6d296efc398fc457515203e9532b5caa24d3e4c3d28dd277059 : update_package.py