Hi Idris Olokunola,
I have tried python requests and was able to load the certificate. But im switching to selenium since the website needs interaction.
Can you give me an input on how I implement in python selenium. Im in ubuntu.
Thanks.
Here is the flow
1. Create a temporary certificate
2. Create firefox profile
3. Import the certificate using certutil
4. Load the page
Here is my initial implementation:
import tempfile
import subprocess
import shutil
import os
import asyncio
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
async def import_ssl(cert_path, profile_path, name):
subprocess.run([
"certutil", "-A",
"-n", name,
"-t", "u,u,u",
"-i", cert_path,
"-d", f"sql:{profile_path}"
], capture_output=True, text=True)
async def create_certificate(cert) -> str:
ssl_cert = tempfile.NamedTemporaryFile(
delete=False, suffix=".pem", mode="w"
)
ssl_cert.write(cert)
ssl_cert.close()
return ssl_cert.name
async def initialize_profile(resource):
profile_path = os.path.join(dir, 'Profiles', resource)
os.makedirs(profile_path, exist_ok=True)
# Create Firefox profile
subprocess.run(["firefox", "-CreateProfile", f"{resource} {profile_path}"], timeout=10)
# Fix permissions
current_user = os.environ.get("USER")
subprocess.run(["chmod", "-R", "u+w", profile_path])
subprocess.run(["chown", "-R", f"{current_user}:{current_user}", profile_path])
# Add custom preferences
prefs_path = os.path.join(profile_path, "user.js")
with open(prefs_path, "a") as f:
f.write('user_pref("security.enterprise_roots.enabled", true);\n')
f.write('user_pref("security.default_personal_cert", "Select Automatically");\n')
return profile_path
async def main(url, cert, resource):
cert_path = await create_certificate(cert)
profile_path = await initialize_profile(resource)
await import_ssl(cert_path, profile_path, resource)
options = Options()
options.add_argument(f"-profile")
options.add_argument(profile_path)
browser = webdriver.Firefox(options=options)
browser.get(url)
asyncio.run(main(url, cert, resource))
The issue im facing, is the certificate is not imported in the firefox profile I have created so that when loading the website, I got this issue.
selenium.common.exceptions.WebDriverException: Message: Reached error page: about:neterror?e=nssFailure2&u=https%3A//testsite.com&c=UTF-8&d=%20
Stacktrace:
RemoteError@chrome://remote/content/shared/RemoteError.sys.mjs:8:8
WebDriverError@chrome://remote/content/shared/webdriver/Errors.sys.mjs:199:5
UnknownError@chrome://remote/content/shared/webdriver/Errors.sys.mjs:910:5
checkReadyState@chrome://remote/content/marionette/navigate.sys.mjs:59:24
onNavigation@chrome://remote/content/marionette/navigate.sys.mjs:348:39
emit@resource://gre/modules/EventEmitter.sys.mjs:156:19
receiveMessage@chrome://remote/content/marionette/actors/MarionetteEventsParent.sys.mjs:33:25
Hopefully you could help. Thanks