Skip to content

Commit

Permalink
Support building pgsodium on windows (#72)
Browse files Browse the repository at this point in the history
* adding scripts to generate root secret key

* add PGDLLEXPORT

* support executing and reading getkey_script on windows

* add visual studio solution/project files

* add windows build instructions and update gitignore

* remove nonfunctional powershell root key script

* use compiler defined _WIN32

* remove check for write permissions

* define getline function for windows builds

* update windows build process to use msbuild from the command line

* - Adding github action to build pgsodium using msbuild and the v143 platform toolset
- Unit tests do not yet run, requires pgtap

* windows tests: adding pgtap and running test suite

---------

Co-authored-by: Michel Pelletier <[email protected]>
  • Loading branch information
andrewwasielewski and michelp authored Sep 20, 2023
1 parent 54ee412 commit dc411ab
Show file tree
Hide file tree
Showing 12 changed files with 328 additions and 108 deletions.
58 changes: 56 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,64 @@ name: Tests
on: [push, pull_request]

jobs:
tests:
test_linux:
name: Linux build and tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Checkout source code
uses: actions/checkout@v2

- name: Run tests
run: |
./test.sh
test_windows:
name: Windows build and tests
runs-on: windows-latest
steps:
- name: Checkout source code
uses: actions/checkout@v2

- name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v1

- name: Install dependencies
run: |
Invoke-WebRequest -URI https://download.libsodium.org/libsodium/releases/libsodium-1.0.18-stable-msvc.zip -OutFile libsodium-1.0.18-stable-msvc.zip
tar -xf libsodium-1.0.18-stable-msvc.zip
rm libsodium-1.0.18-stable-msvc.zip
cp .\libsodium\x64\Release\v143\dynamic\libsodium.dll $env:PGROOT\lib
Invoke-WebRequest -URI https://github.com/theory/pgtap/archive/refs/tags/v1.2.0.zip -OutFile pgtap.zip
tar -xf pgtap.zip
rm pgtap.zip
cd pgtap-1.2.0
cp .\sql\pgtap.sql.in .\sql\pgtap.sql
perl.exe '-pi.bak' -e "s/TAPSCHEMA/tap/g" .\sql\pgtap.sql
perl.exe '-pi.bak' -e "s/__OS__/win32/g" .\sql\pgtap.sql
perl.exe '-pi.bak' -e "s/__VERSION__/0.24/g" .\sql\pgtap.sql
perl.exe '-pi.bak' -e "s/^-- ## //g" .\sql\pgtap.sql
cp .\sql\pgtap.sql $env:PGROOT\share\extension
cp .\pgtap.control $env:PGROOT\share\extension
cp .\contrib\pgtap.spec $env:PGROOT\share\contrib
ren $env:PGROOT\share\extension\pgtap.sql $env:PGROOT\share\extension\pgtap--1.2.0.sql
shell: pwsh

- name: Run msbuild
working-directory: ./build
run: |
msbuild pgsodium.vcxproj /p:libsodiumLocation=..\libsodium /p:PostgreSQLLocation=%PGROOT% /p:Configuration=Release /p:Platform=x64 /p:platformToolset=v143
- name: Install pgsodium, update config, and restart
run: |
cp .\build\x64\Release\pgsodium.dll $env:PGROOT\lib
cp pgsodium.control $env:PGROOT\share\extension
cp .\sql\* $env:PGROOT\share\extension
cp .\getkey_scripts\pgsodium_getkey.bat $env:PGDATA\
((Get-Content -Path $env:PGDATA\postgresql.conf) -Replace "#shared_preload_libraries = ''","shared_preload_libraries = 'pgsodium'") | Set-Content -Path $env:PGDATA\postgresql.conf
Add-Content -Path $env:PGDATA\postgresql.conf -Value ("pgsodium.getkey_script = '$env:PGDATA\pgsodium_getkey.bat'" -Replace "\\","/")
& $env:PGBIN\pg_ctl restart -D $env:PGDATA
shell: pwsh

- name: Run pgsodium tests
run: |
& $env:PGBIN\psql -q -U postgres -f .\test\test.sql
shell: pwsh
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,10 @@
*.su
*~

# Visual Studio Build files
build/.vs/
*.vcxproj.user
build/x64/

pgsodium_encrypted_root.key
.ipynb_checkpoints/
107 changes: 107 additions & 0 deletions build/pgsodium.vcxproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
<Project DefaultTargets="Build" ToolsVersion="16.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

<ItemGroup>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>Win64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>Win64</Platform>
</ProjectConfiguration>
</ItemGroup>

<Import Project="$(VCTargetsPath)\Microsoft.Cpp.default.props"/>

<PropertyGroup Label="Globals">
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDynamicLibraries>true</UseDynamicLibraries>
<RootNamespace>pgsodium</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<PlatformToolset>$(platformToolset)</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
<WholeProgramOptimization>true</WholeProgramOptimization>
<LinkIncremental>false</LinkIncremental>
<GenerateManifest>false</GenerateManifest>
<WarningLevel>Level3</WarningLevel>
<IntrinsicFunctions>true</IntrinsicFunctions>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries>
<LinkIncremental>true</LinkIncremental>
<GenerateManifest>false</GenerateManifest>
<WarningLevel>All</WarningLevel>
</PropertyGroup>

<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />

<ItemGroup>
<ClInclude Include="..\src\crypto_aead_det_xchacha20.h" />
<ClInclude Include="..\src\pgsodium.h" />
<ClInclude Include="..\src\signcrypt_tbsbr.h" />
</ItemGroup>

<ItemGroup>
<ClCompile Include="..\src\aead.c" />
<ClCompile Include="..\src\auth.c" />
<ClCompile Include="..\src\box.c" />
<ClCompile Include="..\src\crypto_aead_det_xchacha20.c" />
<ClCompile Include="..\src\derive.c" />
<ClCompile Include="..\src\hash.c" />
<ClCompile Include="..\src\helpers.c" />
<ClCompile Include="..\src\hmac.c" />
<ClCompile Include="..\src\kdf.c" />
<ClCompile Include="..\src\kx.c" />
<ClCompile Include="..\src\pgsodium.c" />
<ClCompile Include="..\src\pwhash.c" />
<ClCompile Include="..\src\random.c" />
<ClCompile Include="..\src\secretbox.c" />
<ClCompile Include="..\src\secretstream.c" />
<ClCompile Include="..\src\sha.c" />
<ClCompile Include="..\src\sign.c" />
<ClCompile Include="..\src\signcrypt.c" />
<ClCompile Include="..\src\signcrypt_tbsbr.c" />
<ClCompile Include="..\src\stream.c" />
</ItemGroup>

<ItemDefinitionGroup>
<ClCompile>
<ExceptionHandling>false</ExceptionHandling>
<SDLCheck>true</SDLCheck>
<CompileAs>CompileAsC</CompileAs>
<AdditionalIncludeDirectories>
$(PostgreSQLLocation)\include\server\port\win32_msvc;
$(PostgreSQLLocation)\include\server\port\win32;
$(PostgreSQLLocation)\include\server;
$(PostgreSQLLocation)\include;
$(libsodiumLocation)\include;
%(AdditionalIncludeDirectories)
</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>

<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>
$(libsodiumLocation)\x64\Release\$(platformToolset)\dynamic;
$(PostgreSQLLocation)\lib;
%(AdditionalLibraryDirectories)
</AdditionalLibraryDirectories>
<AdditionalDependencies>
postgres.lib;
libsodium.lib;
%(AdditionalDependencies)
</AdditionalDependencies>
</Link>

</ItemDefinitionGroup>

<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Targets" />

</Project>
22 changes: 22 additions & 0 deletions build/windows.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#### Building on Windows
---------

- Download [libsodium](https://download.libsodium.org/libsodium/releases/libsodium-1.0.18-stable-msvc.zip) >= 1.018 and unzip
- Download and run the [postgresql installer](https://www.postgresql.org/download/windows/)
- From the `/pgsodium/build` directory, run `msbuild` on `pgsodium.vcxproj`
- `msbuild` can be invoked though the *x64 Native Tools Command Prompt for VS 2022*

The following properties ( **`/p`** or **`/property`** ) must be specified:
- `libsodiumLocation`: root libsodium directory
- `PostgreSQLLocation`: root postgresql directory, typically `C:\Program Files\PostgreSQL\<version>
- `Configuration`: [`Release`, `Debug`]
- `Platform`: [x64]
- `platformToolset`: [`v142`, `v143`]

ie.

```
msbuild pgsodium.vcxproj /p:libsodiumLocation="C:\libsodium" /p:PostgreSQLLocation="C:\Program Files\PostgreSQL\15" /p:Configuration=Release /p:Platform=x64 /p:platformToolset=v143
```

- Copy the `libsodium.dll` (from `libsodium\x64\Release\<platformToolset>\dynamic`) and the newly built `pgsodium.dll` into your `\PostgreSQL\<version>\lib` directory
7 changes: 7 additions & 0 deletions getkey_scripts/pgsodium_getkey.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@echo off
set KEY_FILE="%PGDATA%/pgsodium_root.key"

IF NOT EXIST %KEY_FILE% (
openssl rand -hex 32 > %KEY_FILE%
)
type "%PGDATA%/pgsodium_root.key"
2 changes: 1 addition & 1 deletion src/aead.c
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ pgsodium_crypto_aead_det_keygen (PG_FUNCTION_ARGS)
PG_RETURN_BYTEA_P (result);
}

PG_FUNCTION_INFO_V1 (pgsodium_crypto_aead_det_noncegen);
PGDLLEXPORT PG_FUNCTION_INFO_V1 (pgsodium_crypto_aead_det_noncegen);
Datum
pgsodium_crypto_aead_det_noncegen (PG_FUNCTION_ARGS)
{
Expand Down
2 changes: 1 addition & 1 deletion src/box.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ pgsodium_crypto_box_keypair (PG_FUNCTION_ARGS)
return result;
}

PG_FUNCTION_INFO_V1 (pgsodium_crypto_box_new_seed);
PGDLLEXPORT PG_FUNCTION_INFO_V1 (pgsodium_crypto_box_new_seed);
Datum
pgsodium_crypto_box_new_seed (PG_FUNCTION_ARGS)
{
Expand Down
27 changes: 26 additions & 1 deletion src/pgsodium.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,25 @@
#include "pgsodium.h"

#ifdef _WIN32
#define X_OK 4
#define access _access
size_t getline(char **lineptr, size_t *n, FILE *stream)
{
// We expect 64 bytes, allocate enough to be sure.
const int BUFFERSIZE = 1024;
char *buffer = malloc (BUFFERSIZE);
if (fgets (buffer, BUFFERSIZE - 1 , stream) == NULL)
{
free (buffer);
return -1;
}
*lineptr = buffer;
size_t char_read = strlen (*lineptr);
*n = char_read;
return char_read;
}
#endif

PG_MODULE_MAGIC;

bytea *pgsodium_secret_key;
Expand Down Expand Up @@ -136,7 +156,12 @@ _PG_init (void)
proc_exit (1);
}

char_read = getline (&secret_buf, &secret_len, fp);
if ((char_read = getline (&secret_buf, &secret_len, fp)) == -1)
{
ereport(ERROR, errmsg("unable to read secret key"));
proc_exit (1);
}

if (secret_buf[char_read - 1] == '\n')
secret_buf[char_read - 1] = '\0';

Expand Down
Loading

0 comments on commit dc411ab

Please sign in to comment.