--- src/network/network_func.h.orig	2021-10-17 09:31:25 UTC
+++ src/network/network_func.h
@@ -73,7 +73,8 @@ void NetworkServerShowStatusToConsole();
 bool NetworkServerStart();
 void NetworkServerNewCompany(const Company *company, NetworkClientInfo *ci);
 bool NetworkServerChangeClientName(ClientID client_id, const std::string &new_name);
-
+void NetworkSavePassword();
+void NetworkLoadPassword();
 
 void NetworkServerDoMove(ClientID client_id, CompanyID company_id);
 void NetworkServerSendRcon(ClientID client_id, TextColour colour_code, const std::string &string);
--- src/network/network_server.cpp.orig	2021-10-17 09:31:25 UTC
+++ src/network/network_server.cpp
@@ -32,6 +32,7 @@
 #include <mutex>
 #include <condition_variable>
 
+#include "../fileio_func.h"
 #include "../safeguards.h"
 
 
@@ -439,6 +440,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Send
 	/* Reset 'lag' counters */
 	this->last_frame = this->last_frame_server = _frame_counter;
 
+	Debug( net, 1, "requesting GAME password" );
 	auto p = std::make_unique<Packet>(PACKET_SERVER_NEED_GAME_PASSWORD);
 	this->SendPacket(std::move(p));
 	return NETWORK_RECV_STATUS_OKAY;
@@ -1563,6 +1565,9 @@ static void NetworkAutoCleanCompanies()
 				IConsolePrint(CC_INFO, "Auto-removed protection from company #{}.", c->index + 1);
 				_network_company_states[c->index].months_empty = 0;
 				NetworkServerUpdateCompanyPassworded(c->index, false);
+				if (_settings_client.network.save_password) {
+					NetworkSavePassword( );
+				}
 			}
 			/* Is the company empty for autoclean_novehicles-months, and has no vehicles? */
 			if (_settings_client.network.autoclean_novehicles != 0 && _network_company_states[c->index].months_empty > _settings_client.network.autoclean_novehicles && vehicles_in_company[c->index] == 0) {
@@ -1656,6 +1661,9 @@ void NetworkServerSetCompanyPassword(CompanyID company
 	}
 
 	NetworkServerUpdateCompanyPassworded(company_id, !_network_company_states[company_id].password.empty());
+	if (_settings_client.network.save_password) {
+		NetworkSavePassword( );
+	}
 }
 
 /**
@@ -2022,6 +2030,49 @@ bool NetworkCompanyHasClients(CompanyID company)
 		if (ci->client_playas == company) return true;
 	}
 	return false;
+}
+
+void NetworkSavePassword( )
+{
+	static FILE *file_pointer;
+	std::string password_file_name;
+
+	password_file_name = fmt::format("{}.pwd", _settings_game.game_creation.generation_seed);
+	Debug( net, 0, "Saving companies password to %s", password_file_name );
+	file_pointer = FioFOpenFile( password_file_name, "wb", SAVE_DIR );
+
+	if (file_pointer != NULL) {
+		for( CompanyID l_company = (CompanyID)0; l_company < MAX_COMPANIES; l_company++ ) {
+			if (NetworkCompanyIsPassworded(l_company)) {
+				fwrite(_network_company_states[l_company].password.c_str(), _network_company_states[l_company].password.size(), 1, file_pointer);
+			}
+			fwrite( "\n", 1, 1, file_pointer );
+		}
+		fclose(file_pointer);
+	}
+}
+
+void NetworkLoadPassword( )
+{
+	static FILE *file_pointer;
+	char password[NETWORK_PASSWORD_LENGTH];
+	std::string password_file_name;
+
+	password_file_name = fmt::format("{}.pwd", _settings_game.game_creation.generation_seed);
+	file_pointer = FioFOpenFile( password_file_name, "rb", SAVE_DIR );
+	if (file_pointer != NULL) {
+		Debug( net, 0, "Loading password from %s", password_file_name );
+		for( CompanyID l_company = (CompanyID)0; l_company < MAX_COMPANIES; l_company++ ) {
+			fgets( password, sizeof( password), file_pointer);
+			if (strlen(password)>1) {
+				fseek( file_pointer, 1L, SEEK_CUR );
+				_network_company_states[l_company].password = password;
+				NetworkServerUpdateCompanyPassworded(l_company, !_network_company_states[l_company].password.empty());
+			}
+		}
+	} else {
+		Debug( net, 0, "Password file %s not found", password_file_name );
+	}
 }
 
 
--- src/openttd.cpp.orig	2021-10-17 09:31:25 UTC
+++ src/openttd.cpp
@@ -1046,6 +1046,10 @@ void SwitchToMode(SwitchMode new_mode)
 				OnStartGame(_network_dedicated);
 				/* Decrease pause counter (was increased from opening load dialog) */
 				Command<CMD_PAUSE>::Post(PM_PAUSED_SAVELOAD, false);
+				// Try to load password
+				if (_settings_client.network.save_password) {
+					NetworkLoadPassword( );
+				}
 			}
 			break;
 		}
--- src/settings_type.h.orig	2021-10-17 09:31:25 UTC
+++ src/settings_type.h
@@ -296,6 +296,7 @@ struct NetworkSettings {
 	std::string last_joined;                              ///< Last joined server
 	UseRelayService use_relay_service;                    ///< Use relay service?
 	ParticipateSurvey participate_survey;                 ///< Participate in the automated survey
+	bool   save_password;                                 ///< If password file is used
 };
 
 /** Settings related to the creation of games. */
--- src/table/settings/network_settings.ini.orig	2021-10-17 09:31:25 UTC
+++ src/table/settings/network_settings.ini
@@ -265,3 +265,8 @@ str      = STR_CONFIG_SETTING_USE_RELAY_SERVICE
 flags    = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_NETWORK_ONLY
 def      = false
 cat      = SC_EXPERT
+
+[SDTC_BOOL]
+var     = network.save_password
+flags   = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC
+def     = false
