Repository: certbot/certbot

Issue:
An unexpected error occurred: KeyError: '<domain_here>'
Getting 
```Cleaning up challenges
Not cleaning up the web.config file in C:\inetpub\wwwroot\.well-known\acme-challenge because it is not generated by Certbot.
An unexpected error occurred:
KeyError: 'domain2'
```

https://github.com/certbot/certbot/blob/b1edda8a65cc9d9d143ec67f4d79aafc04670793/certbot/certbot/_internal/plugins/webroot.py#L220

It turns out that if we are trying to set multiple domains (-d domain1 -d domain2) and only one wwwroot for them
certbot end ups with this:

```
Using the webroot path C:\inetpub\wwwroot for all unmatched domains.
A web.config file has not been created in C:\inetpub\wwwroot\.well-known\acme-challenge because another one already exists.
{'domain1': 'C:\\inetpub\\wwwroot\\.well-known\\acme-challenge'}
{'domain1': 'C:\\inetpub\\wwwroot\\.well-known\\acme-challenge'}
```
while it should keep track of both domains

to fix this changed `return` to `continue` so it iterates all the domains instead of exiting 
created PR for that: #9090 

Certificate issuing on Window while having web.confing and more then …

Getting 
```Cleaning up challenges
Not cleaning up the web.config file in C:\inetpub\wwwroot\.well-known\acme-challenge because it is not generated by Certbot.
An unexpected error occurred:
KeyError: 'domain2'
```

https://github.com/certbot/certbot/blob/b1edda8a65cc9d9d143ec67f4d79aafc04670793/certbot/certbot/_internal/plugins/webroot.py#L220

It turns out that if we are trying to set multiple domains (-d domain1 -d domain2) and only one wwwroot for them
certbot end ups with this:

```
Using the webroot path C:\inetpub\wwwroot for all unmatched domains.
A web.config file has not been created in C:\inetpub\wwwroot\.well-known\acme-challenge because another one already exists.
{'domain1': 'C:\\inetpub\\wwwroot\\.well-known\\acme-challenge'}
{'domain1': 'C:\\inetpub\\wwwroot\\.well-known\\acme-challenge'}
```
while it should keep track of both domains

to fix this changed `return` to `continue` so it iterates all the domains instead of exiting 



Discussion:

Resolving patch:
diff --git a/certbot/certbot/_internal/plugins/webroot.py b/certbot/certbot/_internal/plugins/webroot.py
--- a/certbot/certbot/_internal/plugins/webroot.py
+++ b/certbot/certbot/_internal/plugins/webroot.py
@@ -221,7 +221,7 @@ def _create_challenge_dirs(self):
                 if os.path.exists(web_config_path):
                     logger.info("A web.config file has not been created in "
                                 "%s because another one already exists.", self.full_roots[name])
-                    return
+                    continue
                 logger.info("Creating a web.config file in %s to allow IIS "
                             "to serve challenge files.", self.full_roots[name])
                 with safe_open(web_config_path, mode="w", chmod=0o644) as web_config:


Test patch:
diff --git a/certbot/tests/plugins/webroot_test.py b/certbot/tests/plugins/webroot_test.py
--- a/certbot/tests/plugins/webroot_test.py
+++ b/certbot/tests/plugins/webroot_test.py
@@ -115,6 +115,22 @@ def test_foreign_webconfig_file_handling(self, mock_get_utility):
         from certbot._internal.plugins.webroot import _WEB_CONFIG_SHA256SUMS
         self.assertTrue(webconfig_hash not in _WEB_CONFIG_SHA256SUMS)
 
+    @unittest.skipIf(filesystem.POSIX_MODE, reason='Test specific to Windows')
+    def test_foreign_webconfig_multiple_domains(self):
+        # Covers bug https://github.com/certbot/certbot/issues/9091
+        achall_2 = achallenges.KeyAuthorizationAnnotatedChallenge(
+            challb=acme_util.chall_to_challb(challenges.HTTP01(token=b"bingo"), "pending"),
+            domain="second-thing.com", account_key=KEY)
+        self.config.webroot_map["second-thing.com"] = self.path
+
+        challenge_path = os.path.join(self.path, ".well-known", "acme-challenge")
+        filesystem.makedirs(challenge_path)
+
+        webconfig_path = os.path.join(challenge_path, "web.config")
+        with open(webconfig_path, "w") as file:
+            file.write("something")
+        self.auth.perform([self.achall, achall_2])
+
     @test_util.patch_display_util()
     def test_webroot_from_list_help_and_cancel(self, mock_get_utility):
         self.config.webroot_path = []