Line data Source code
1 : /* ------------------------------------------------------------------------- 2 : * 3 : * auth_delay.c 4 : * 5 : * Copyright (c) 2010-2024, PostgreSQL Global Development Group 6 : * 7 : * IDENTIFICATION 8 : * contrib/auth_delay/auth_delay.c 9 : * 10 : * ------------------------------------------------------------------------- 11 : */ 12 : #include "postgres.h" 13 : 14 : #include <limits.h> 15 : 16 : #include "libpq/auth.h" 17 : #include "port.h" 18 : #include "utils/guc.h" 19 : #include "utils/timestamp.h" 20 : 21 0 : PG_MODULE_MAGIC; 22 : 23 : /* GUC Variables */ 24 : static int auth_delay_milliseconds = 0; 25 : 26 : /* Original Hook */ 27 : static ClientAuthentication_hook_type original_client_auth_hook = NULL; 28 : 29 : /* 30 : * Check authentication 31 : */ 32 : static void 33 0 : auth_delay_checks(Port *port, int status) 34 : { 35 : /* 36 : * Any other plugins which use ClientAuthentication_hook. 37 : */ 38 0 : if (original_client_auth_hook) 39 0 : original_client_auth_hook(port, status); 40 : 41 : /* 42 : * Inject a short delay if authentication failed. 43 : */ 44 0 : if (status != STATUS_OK) 45 : { 46 0 : pg_usleep(1000L * auth_delay_milliseconds); 47 : } 48 0 : } 49 : 50 : /* 51 : * Module Load Callback 52 : */ 53 : void 54 0 : _PG_init(void) 55 : { 56 : /* Define custom GUC variables */ 57 0 : DefineCustomIntVariable("auth_delay.milliseconds", 58 : "Milliseconds to delay before reporting authentication failure", 59 : NULL, 60 : &auth_delay_milliseconds, 61 : 0, 62 : 0, INT_MAX / 1000, 63 : PGC_SIGHUP, 64 : GUC_UNIT_MS, 65 : NULL, 66 : NULL, 67 : NULL); 68 : 69 0 : MarkGUCPrefixReserved("auth_delay"); 70 : 71 : /* Install Hooks */ 72 0 : original_client_auth_hook = ClientAuthentication_hook; 73 0 : ClientAuthentication_hook = auth_delay_checks; 74 0 : }