ISSUE: MacOS Sequoia has introduced new security that impacts access to resources on your local network. For me this presented when I attempted to access a database remotely hosted on another computer on my local network. The error presented as a "no path to the client" network issue.
DETAILS: The mechanism for managing access is clear; the first time a program accesses a local network resource, the OS presents a dialog box asking the user if they want to allow this access. The name of the program is then inserted into the system configuration and the user's choice is noted. To see programs that have been granted access you can navigate to Sytem Settings / Privacy & Security / Local Network. You will have to scroll down to find these settings. On that settings page you will see all programs that have accessed a local network device and a slider that allows the user to select to allow or disallow access.
The issue is that there is no manual way to manage the list of programs in this list. The OS manages this list based on the scenario above. Lazarus was not triggering the OS to prompt for permission when a network device was accessed, thus Lazarus was blocked.
SOLUTION: The OS does not prompt for access due to the bundle definition and code signing. Note: I am using Lazarus as built using FPCUpDeluxe so this solution will be specifically attributable to that environment. Although the same process should work for any Lazarus application. This will impact all applications built by Lazarus as well. The steps to resolve this for Lazarus (so that you can access local network resources at design time) will have to be applied for each program developed for the Mac that will run on Sequoia or later OS releases that have features that access local network resources.
First local your Lazarus application. This has to be in a Mac application bundle (e.g. a directory with the name <program>.app). FPCUpDeluxe uses a strategy that allows for multiple development environments to exist so the bundle is a little different. To support the multiple environments FPCUpDeluxe creates an application bundle called startlazarus.app. Your bundle may be named lazarus.app. Note that while these are directories the Mac presents these bundles as an application. For the rest of this writeup I will refer to the application bundle (startlazarus.app for example) as the app root.
After you find your bundle perform the following steps.
- Open the <app root>/Contents/Info.plist file for editing. In the plist add the following lines after <dict> in the document:
<key>CFBundleIdentifier</key>
<string>com.self.lazarus</string>
<key>CFBundleName</key>
<string>startlazarus</string>
<key>CFBundleVersion</key>
<string>4.99</string>
<key>CFBundleExecutable</key>
<string>startlazarus</string>
The values for CFBundleIdentifier and CFBundleVersion can be whatever you choose. I have used "com.self.lazarus" and "4.99" respectively. The remainder need to represent your specific situation. For FPCUpDeluxe, the CFBundleExecutable is "startlazarus". If you installed your Lazarus differently it may be something else; lazarus for example. Check and make sure you get this right. I don't know if CFBundlName has to be the same as the executable, but that is what I used.
- Save the edited Info.plist file.
- Check to see if the executable in the bundle is a symbolic link. It was for my build using FPCUpDeluxe. You can check by executing the following statement
ls -al <app root>/Contents/MacOS
The executable is in this directory. If it is not a symbolic link, you should be good to go. If it is a sym link, you will need to unlink and replace it with a copy of the executable. Use the following:
unlink startlazarus.app/Contents/MacOS/startlazarus
cp startlazarus startlazarus.app/Contents/MacOS
Note that your application bundle and executable may be named something other than startlazarus. Adjust accordingly.
Last, you need to complete the code signing. If you have a developer ID use the code signing process as appropriate. For those that don't have an Apple developer ID you can use the generic code signing process below. Clearly if you are going to distribute your application widely then you should be following the Apple developer methods here. For the rest of us the following will suffice.
codesign --force --deep --sign - startlazarus.app
Now, start Lazarus by using the "open startlazarus.app" command (or whatever your application bundle is) or by using the application icon. To validate that this is working, you should be able to use a component that accesses a local network resource. For me, I used a TPQConnection to connect to a PostgreSQL server hosted on another machine within my local network. Set the parameters, specifically making the hostname refer to a non-localhost device. Set Connected to TRUE and you should be prompted by the OS to allow/disallow access to the Local Network.
Now, navigate over to System Settings / Privacy & Security / Local Network and you should see the entry there for lazarus that you can manage as appropriate. Note the request for access permission is only performed once, the first time you access Local Network devices. From that point on it is handled in System Settings.
CAVEATS: By doing these steps for Lazarus itself, you will accommodate Lazarus access to Local Network resources in design and developer mode, however, any programs that you create will have to have the same process applied. The key is to go to Project Options, under Application, scroll to the bottom and press the "Create Application Bundle" button. This will create a new <app root> that you will have to follow the same steps as above for your application.
QUESTIONS: I don't know what the impact is of removing the sym link in the above steps will be in recursive development. My guess is that you will have to perform some of these steps after rebuilding the executable. The only reason for removing the link is that the codesign program does not allow a link. I don't know yet if after signing you can replace the link. I may play with it a bit and I will post my results. Certainly you will have to be careful if you are distributing an application to make sure that the application bundle has the most current executable.
The bigger question is whether these changes can be accommodated into the process at the start. I am not certain how the Info.plist is generated initially, but it would be nice if that could be modified and maybe the specific settings could be captured in a config setting. For all I know, they may be already! If someone knows the rationale for the link in the bundle and whether that could be accommodated it would be helpful.
Lastly, I certainly didn't think I would run into this rabbit hole when I decided to migrate my backend database from SQLite to PostgreSQL running on a remote computer, but I have to admit I learned a lot. I hope that sharing this will keep someone else from having to figure this out themselves.