#1 Re: mORMot Framework » TLS support for THttpServer » Yesterday 15:39:49

ab wrote:

On Windows, why not use the http.sys server, which supports TLS out of the box, and has similar performance to IIS (so is faster than the socket layer)?
Only because it is easier to setup?

First, I would like to have one codebase for Windows and Linux. And, ideally, certificate renewal infrastructure/code.

And in THttpServer I use feature called "stream": when processing special URL, I move socket from working thread to array of stream subscribers, and convert socket to async. Later, when data become availabe, I send it to all stream subscribers (subscriber is array of async sockets). Not sure yet if this will work with TLS.

Now I try Linux, but in my Ubuntu 22.04 installed OpenSSL 3, and there is some functions were renamed (e.g. EVP_PKEY_size -> EVP_PKEY_get_size).

#2 Re: mORMot Framework » TLS support for THttpServer » Yesterday 11:39:29

About perfomance.

First call to AcceptSecurityContext takes about 1 ms, then about 2 ms we wait client answer, and second call to AcceptSecurityContext takes 1 ms.
Summary 4 ms for establishing TLS connection.

Some numbers, when testing with Apache benchmarking tool.

> abs.exe -n 10000 -c 100 https://test:8888/echo
Server Software:        mORMot2
Server Hostname:        test
Server Port:            8888
SSL/TLS Protocol:       TLSv1.2,ECDHE-RSA-AES256-GCM-SHA384,2048,256
Server Temp Key:        ECDH P-384 384 bits
TLS Server Name:        test

Document Path:          /echo
Document Length:        53 bytes

Concurrency Level:      100
Time taken for tests:   49.170 seconds
Complete requests:      10000
Failed requests:        0
Keep-Alive requests:    0
Total transferred:      1560000 bytes
HTML transferred:       530000 bytes
Requests per second:    203.38 [#/sec] (mean)
Time per request:       491.698 [ms] (mean)
Time per request:       4.917 [ms] (mean, across all concurrent requests)
Transfer rate:          30.98 [Kbytes/sec] received

For comparision, numbers for server without TLS:

Requests per second:    3488.43 [#/sec] (mean)
Time per request:       28.666 [ms] (mean)
Time per request:       0.287 [ms] (mean, across all concurrent requests)
Transfer rate:          531.44 [Kbytes/sec] received

And IIS:

Server Software:        Microsoft-IIS/10.0
Server Hostname:        test
Server Port:            443
SSL/TLS Protocol:       TLSv1.2,ECDHE-RSA-AES256-GCM-SHA384,2048,256
Server Temp Key:        ECDH P-384 384 bits
TLS Server Name:        test

Document Path:          /iisstart.htm
Document Length:        696 bytes

Concurrency Level:      100
Time taken for tests:   30.434 seconds
Complete requests:      10000
Failed requests:        0
Total transferred:      9390000 bytes
HTML transferred:       6960000 bytes
Requests per second:    328.58 [#/sec] (mean)
Time per request:       304.343 [ms] (mean)
Time per request:       3.043 [ms] (mean, across all concurrent requests)
Transfer rate:          301.30 [Kbytes/sec] received

#3 Re: mORMot Framework » TLS support for THttpServer » Yesterday 06:02:20

ab wrote:

Could you share the source code to the point where you are currently?

https://gist.github.com/achechulin/fb78 … aa58377ef5

I started from http-server-raw example, and modified mORMot 2 code in destructive way - change TLS client code to work in server mode.

First, THttpAsyncServer changed to THttpServer.

Then, TCrtSocket.OpenBind changed to always call DoTlsHandshake for accepted socket.

Third, TSChannelClient.AfterConnection load server certificate (mycert.pfx) on first use, and then call AcquireCredentialsHandle with that certificate. In HandshakeLoop InitializeSecurityContext changed to AcceptSecurityContext.

I use Let's Encrypt sertificate, converted to PFX:

openssl pkcs12 -inkey privkey.pem -in cert.pem -export -out mycert.pfx

#4 mORMot Framework » TLS support for THttpServer » 2022-05-19 12:04:16

Chaa
Replies: 7

Hello, ab!

I need TLS support for THttpServer (mORMot2).

There is some support for it in TCrtSocket: parameters in TNetTlsContext and encryption layer abstraction in INetTls. But only for client connections. So, I started trying to make it for server.

At first step I changed some code in mormot.net.sock.pas for Windows, i.e. add some Cert* functions and change call from InitializeSecurityContext to AcceptSecurityContext. Now my THttpServer serves HTTPS (tested in Chrome and Firefox).

At next step I try to work on TLS for Linux and OpenSSL.

But for server TLS we need some state, shared for all accepted connections, like certificate (CredHandle or SSL_CTX). So we need to do some refactoring.

I think we can change TNetTlsContext to interface like INetTlsContext. Then implement it for client and server. For server, we store shared state in underlying object. All accepted sockets will get a reference to parent socket INetTlsContext.

Sure, INetTls will be implemented differently for client and server.

Client code may looks like this:

with THttpClientSocket.Create do
  try
    TLS := NewTlsContext();
    TLS.WithPeerInfo := true;
    // Or maybe:
    // TLS := NewTlsContext({WithPeerInfo=}true, {IgnoreCertificateErrors=}true);
    OpenBind('synopse.info', '443', {bind=}false, {tls=}true);
    writeln(Secure.PeerInfo);
    writeln(Secure.CipherName);
    writeln(Get('/forum/', 1000), ' len=', ContentLength);
  finally
    Free;
  end;

Server side:

  fHttpServer := THttpServer.Create(...);
  fHttpServer.WaitStarted;
  fHttpServer.Sock.TLS := NewServerTlsContext('mycert.pfx');

Maybe you can suggest other solutions.

#7 Re: mORMot Framework » Windows authentication 64bit » 2021-12-03 05:31:40

There is a bug in SecDecrypt.

Documentation says that "encrypted message is decrypted in place, overwriting the original contents of its buffer" when we pass SECBUFFER_DATA. But we pass SECBUFFER_STREAM and empty SECBUFFER_DATA and expect that provider allocate memory for SECBUFFER_DATA. But it does not. So call to FreeContextBuffer fails.

I will investigate further and make a patch.

juwo, try remove line

FreeContextBuffer(InBuf[1].pvBuffer);

from the end of function SecDecrypt (SynSSPI.pas). This should solve your problem.

#8 Re: mORMot Framework » CRITICAL - Load balancer & client IP address problem » 2021-05-21 03:26:39

And in case if reverse proxy is not used, it is mandatory that RemoteIPHeader to be empty.
In other case client can arbitrarily change RemoteIP, that is possible security risk.

#9 Re: mORMot Framework » Access violation on published TSQLRecord properties » 2021-03-26 09:01:09

OK, thank's!
Yes, It's really old code, from about 2012.

#10 Re: mORMot Framework » Access violation on published TSQLRecord properties » 2021-03-26 05:52:41

I propose this changes:

--- a/mORMot.pas
+++ b/mORMot.pas
@@ -51009,11 +51009,11 @@ var Added: boolean;
       tkClass: begin
         Obj := P^.GetObjProp(Value);
-        if not(woDontStore0 in Options) or not IsObjectDefaultOrVoid(Obj) then
           if PropIsIDTypeCastedField(P,IsObj,Value) then begin
             HR(P);
             Add(PtrInt(Obj)); // not true instances, but ID
-          end else if Obj<>nil then begin
+          end else if (Obj<>nil) and
+            (not(woDontStore0 in Options) or not IsObjectDefaultOrVoid(Obj)) then begin
             HR(P); // TPersistent or any class defined with $M+
             WriteObject(Obj,Options);
           end;

#11 Re: mORMot Framework » Access violation on published TSQLRecord properties » 2021-03-26 03:32:36

That's worked fine until commit https://github.com/synopse/mORMot/commi … 6b9bf508ba because there is function PropIsIDTypeCastedField that can distinguish TObject and ID fields.

So, if it is designed, how can I call interface-based services with TSQLRecord as parameters?

#12 mORMot Framework » Access violation on published TSQLRecord properties » 2021-03-25 05:57:23

Chaa
Replies: 5

When I use TSQLRecord published properties, as documented in 5.1.7. TSQLRecord fields, there is access violation in TJSONSerializer.WriteObject when handling woDontStore0 option. And woDontStore0 in DEFAULT_WRITEOPTIONS so I can not avoid it.
Minimal code:

type
  TSQLFolder = class (TSQLRecord)
  end;
  TSQLFile = class (TSQLRecord)
      FFolder: TSQLFolder;
  published
      property Folder: TSQLFolder read FFolder write FFolder;
  end;
var
  f: TSQLFile;
begin
  f := TSQLFile.Create;
  f.Folder := TSQLFolder(10);
  ObjectToJSON(f, [woDontStore0]);
end;

Exception EAccessViolation raised with message "Read of address 0000000A".
The problem is in TJSONSerializer.WriteObject for Kind = tkClass.
Function IsObjectDefaultOrVoid called before PropIsIDTypeCastedField, and it is treated Obj as TObject, not as an ID.

#13 Re: mORMot Framework » mORMot 2 proposal: rename RawUTF8 type to Utf8 ? » 2020-12-30 04:31:26

I think that UTF8String is better than UTF8.
And RTL has UTF8String defined exactly as in mORMot.
So we can use RTL type in new Delphi versions, and define it for old versions.

#14 Re: mORMot Framework » Error 6 - The handle is invalid when trying to start services » 2020-12-18 04:12:14

Your OpenSCManager failed with ERROR_ACCESS_DENIED.
I think you must use "Run as Administrator".

#15 Re: mORMot Framework » Json Array de-serialization problem » 2020-03-05 11:51:56

Type TStVATDetail has type information, but TStVATDetails does not, because compiler not needed for it - no managed fields in record, so compiler might simply free memory used for array.
Try change your record:

TStVATDetail = packed record
    u32VAT: Integer;
    u32Amount: Integer;
    u16VATPercentage: UInt16;
    s: String;
  end;

And you will see that code now works.

#16 Re: mORMot Framework » Json Array de-serialization problem » 2020-03-05 10:28:26

Delphi does not create RTTI information for records without managed fields (like String, Variant, Array, Interface).

So there are 3 option:
1. Add managed field
2. Use text-based definition https://synopse.info/files/html/Synopse … #TITLE_242
3. Use custom serialization

#17 Re: mORMot Framework » Json Array de-serialization problem » 2020-03-05 09:36:09

DynArrayLoadJSON modified JSON-buffer in-place when parsing.
You pass const string and function fails. Try:

var
  Taxes: TStVATDetails;
  S: RawUTF8;
begin
  S:= Json;
  if DynArrayLoadJSON(Taxes, UniqueRawUTF8(S), TypeInfo(TStVATDetails)) then...
end;

#18 Re: mORMot Framework » Revision 2.x of the framework » 2020-03-05 08:48:21

I use Delphi XE5 on Windows and FPC on Linux, so I hope they will be supported at the same level.

As you can see earlier, I am interested in date/time milliseconds resolution.
Now, I am working on some patches for SynSQLite.Utf8SQLDateTime and mORMot.TJSONSerializer.WriteObject.

Maybe, it's time to think about adding ftDateMS to TSQLDBFieldType (datetime vs datetime2 for MS SQL, datetime vs datetime(3) for MySQL). And maybe even about milliseconds in TTimeLog.

#19 Re: mORMot Framework » Support for milliseconds in TDateTime » 2020-02-11 08:04:04

Milliseconds again.

I have a problem with floating point numbers rounding error.
There are assumtion, across a framework, that if two dates E and F differs in milliseconds, then abs(E-F) < 1/MSecsPerDay.
This is not true - thanks to floating point.
Test case:

procedure TTestLowLevelCommon.Iso8601DateAndTime;
  procedure Test(D: TDateTime; Expanded: boolean);
  begin
    ...
    s := DateTimeToIso8601(D,Expanded);
    E := Iso8601ToDateTime(s+'.001');
    F := Iso8601ToDateTime(s+'.002');
    Check(abs(E-F)<1/MSecsPerDay);           // <- failed
    Check(not SameValue(E,F,1/MSecsPerDay)); // <- failed
  end;
begin
  ...
end;

My real problem is in SynSQLite.Utf8SQLDateTime, that uses SameValue as in test case.

Some numbers:
1/MSecsPerDay = 1.15740740740741E-8
2020-01-01T00:00:00.002 - 2020-01-01T00:00:00.001 = 1.15687726065516E-8

The solution may be in defining the const for milliseconds precision.

const
  MSecsPrecision = 0.0000000115;

#20 Re: mORMot Framework » Change view path on fly for MVC Web Application » 2019-09-10 03:47:36

If you need per-user template, you can do it in that way:
1. Define ShowInvoicePreview.html like
{{#Scope}}{{{Result}}}{{/Scope}}
2. In ShowInvoicePreview function call GetUserInvoicePreview.
3. Create GetUserInvoicePreview as in example:

type
    TMyAppViews = class(TMVCViewsMustache);

function TMyApp.GetUserInvoicePreview(var Scope: Variant): RawUTF8;
var
    LTemplate: RawUTF8;
    LMustache: TSynMustache;
    LContext: Variant;
begin
    LTemplate := <Load from DB...>;
    LContext := _ObjFast(['main', GetViewInfo(-1), 'Scope', Scope]);
    // TSynMustache maintain internal template cache
    LMustache := TSynMustache.Parse(LTemplate);
    Result := LMustache.Render(LContext,
        TMyViews(FViews).fViewPartials,
        TMyViews(FViews).fViewHelpers);
end;

procedure TMyApp.ShowInvoicePreview(var Scope: Variant);
var
    LContent: RawUTF8;
begin
    Scope := _ObjFast([...]);
    LContent := GetUserInvoicePreview(Scope);
    _ObjAddProps(['Result', LContent], Scope);
end;

#21 Re: mORMot Framework » Websockets client - how to detect the closing of the socket? » 2019-06-15 04:22:11

jaclas wrote:

If after unexpected closing the websocket connection I will resume this connection again (start websocket from client side) then next connection break (simulated by TCPView -> Close connection) no longer triggers the OnWebSocketsClosed event.

I have a similar problem:
https://synopse.info/forum/viewtopic.ph … 392#p29392

#22 Re: mORMot Framework » Download particular checkin » 2019-06-01 05:58:10

You can login in fossil (https://synopse.info/fossil/login) with anonymous login and then download as zip.

#23 Re: mORMot Framework » OnWebSocketsClosed not fired in last release. » 2019-04-18 09:31:39

I change function TWebSocketProcess.NotifyCallback so that it returns STATUS_NOTIMPLEMENTED when SendFrame failed, indicating that connection broken. Patch:

--- SynBidirSock.org
+++ SynBidirSock.pas
@@ -2435,8 +2435,10 @@ begin
   try
     if (i>2) and (WebSocketLog<>nil) then
       WebSocketLog.Add.Log(sllWarning,'NotifyCallback with fProcessCount=%',[i],self);
-    if not SendFrame(request) then
+    if not SendFrame(request) then begin
+      result := STATUS_NOTIMPLEMENTED;
       exit;
+    end;
     if aMode=wscBlockWithoutAnswer then begin
       result := STATUS_SUCCESS;
       exit;

You can try. If it helps, then we can create pull request.

#24 Re: mORMot Framework » OnWebSocketsClosed not fired in last release. » 2019-04-11 10:49:41

I have similar problem: TWebCrtSocketProcess.ProcessLoop does not properly detect network errors and not finished.
Instead, all requests completed with error "'Not Found' (404 - Network problem or request timeout)".

#25 Re: mORMot Framework » Delphi 10.3.1 mORMot Compile fails » 2019-02-15 04:10:18

In 1.18.5037 there is

{$elseif defined(VER330)}'Delphi 10.3 Rio'
{$elseif defined(VER340)}'Delphi 10.4 Next'

See latests trunk on GitHub: https://github.com/synopse/mORMot

#26 Re: PDF Engine » Problem converting multipage TIFF to PDF » 2019-02-13 12:21:23

Try to add call to procedure fImageSet in the end of TTiffImage.SelectPage.

#28 Re: mORMot Framework » Change view path on fly for MVC Web Application » 2019-02-07 04:11:13

Class TMVCViewsMustache has virtual methods FindTemplates, GetTemplate and GetStaticFile.
So you can customize process of reading templates and static files.

For example, see Virtual methods for loading templates in MVC Web App.

#29 Re: mORMot Framework » OpenHttp raises ECrtSocket exception » 2019-02-05 05:00:54

damiand, I see two problems with your server:

1. Your server has requested a client certificate, but do not require it.
You can avoid problem with it by adding ISC_REQ_USE_SUPPLIED_CREDS to ISC_REQ_FLAGS const.

2. First call to Recv returns only 4096 bytes and InitializeSecurityContext fails with SEC_E_INVALID_TOKEN (but should be SEC_E_INCOMPLETE_MESSAGE, I guess).
If I insert some delay before first call to Recv, then I recieve 4995 bytes and handshake succeeded.

#30 Re: mORMot Framework » OpenHttp raises ECrtSocket exception » 2019-02-05 04:03:14

In my Windows 10, the real error message is SEC_E_INVALID_TOKEN: The token supplied to the function is invalid, when function InitializeSecurityContext called second time in TSChannelClient.HandshakeLoop.

Commit [4dd8e7cce5] not important here, as TSChannelClient.Send is not called at all.

#31 Re: mORMot Framework » mormot httpapiserver not suppport fontawesome? » 2019-01-11 06:44:44

Sample "09 - HttpApi web server" does not handle "?" in URL.

You may do it yourself or use more feature-rich http server like sample "30 - MVC Server" or Memcached Boilerplate HTTP Server for Synopse mORMot Framework.

#32 Re: mORMot Framework » mormot httpapiserver not suppport fontawesome? » 2019-01-11 05:55:38

Browser requests file "...webfont.woff?v=4.5.0", but your implementation cannot process "?v=4.5.0" at the end of file.
If I remove "?v=4.5.0" from URL manually, then file returned OK.

Do you use TSQLRestServerURIContext.ReturnFileFromFolder or other function?

#33 Re: PDF Engine » Out of memory when converting TIFF to PDF / A » 2018-12-20 06:12:54

You can use SaveToStreamDirectBegin/SaveToStreamDirectPageFlush/SaveToStreamDirectEnd to write PDF page by page and reduce memory usage.

Also, to create PDF of smaller size, you can use CreateOrGetImage instead of TPdfImage.Create and set ForceJPEGCompression.

#34 Re: mORMot Framework » Need help, how can i connect to mormot server via .net webapp with c#? » 2018-12-05 10:17:38

TSQLRestServerAuthenticationDefault class implements a proprietary (mORMot) RESTful Authentication with URI signing.
In your example you must use TSQLRestServerAuthenticationHttpBasic for AuthenticationRegister.

#35 Re: mORMot Framework » SynLog - To allow ignoring exceptions with code » 2018-10-17 04:11:14

/// callback signature used by TSynLogFamilly.OnBeforeException
// - should return true to log the exception, or false to ignore it
TSynLogOnBeforeException = function(aExceptionContext: TSynLogExceptionContext): boolean of object;

ab, please correct description: should return false to log the exception, or true to ignore it.

#37 Re: mORMot Framework » Variable input parameters as array on MVCViewModel » 2018-09-24 09:12:13

You can access raw input parameters:

var
  i: Integer;  
  LContacts: TRawUTF8List;
begin
  with CurrentServiceContext.Request do
  begin
    for i := 0 to (Length(InputPairs) shr 1) - 1 do
    begin
      if InputPairs[i * 2] = 'Contacts' then
      begin
        LContacts.Add(InputPairs[i * 2 + 1]);
      end;
    end;
  end;
end;

#40 Re: mORMot Framework » How to pass xml to interface based service » 2018-07-26 10:49:21

And try use RawJSON:

function TNotifySrv.Test(notify: RawJSON): UTF8String;

#41 Re: mORMot Framework » Windows Authentication for MVC/MVVM » 2018-06-19 06:23:47

There is two optons:

1. If you use TSQLAuthUser/TSQLAuthGroup for user management, then you can call TSQLRestServer.Auth, check it results and create web session on success.

2. If you use other user management (like in sample "30 - MVC Server"), then you can copy some code from TSQLRestServerAuthenticationSSPI.Auth to your web app.

Sample code:

Copy MVCViewModel.pas from mORMotMVC-20180619.zip to your "30 - MVC Server" folder and rebuild server.
Add row to TSQLAuthor table with the LoginName in form 'DomainName\UserName'.
And navigate to http://localhost:8092/blog/SingleSignOn

P.S.
We discuss Linux support for Windows authentication, and we are interested in your opinion:
https://synopse.info/forum/viewtopic.php?id=931&p=2

#42 Re: mORMot Framework » Windows authentication on the server » 2018-06-14 08:46:27

After some investigation I see that fully qualified domain name makes problem too.

For example, QueryContextAttributes(SECPKG_ATTR_NAMES) return name only in short format, and TranslateName(NameDnsDomain) returns error in my domain. I can avoid this by using TranslateName(NameUserPrincipal) and convert user name as in SynGSSAPIAuth.pas, but it is strange and is difficult to predict the consequences.

So, for maximum backward compatibility, I propose to leave Windows part as it is.
And in Linux part add dictionary to convert FQDN to short NetBIOS names (used only in rare cases, if automatic conversion do it wrong).

var
  /// Dictionary for converting fully qualified domain names to NT4-style NetBIOS names
  // - to use same value for TSQLAuthUser.LogonName on all platforms user name
  // changed from 'username@MYDOMAIN.TLD' to 'MYDOMAIN\username'
  // - when converting fully qualified domain name to NT4-style NetBIOS name 
  // ServerDomainMap first checked. If domain name not found, then it's truncated on first dot,
  // e.g. 'user1@CORP.ABC.COM' changed to 'CORP\user1'
  // - you can change domain name conversion by registering names at server startup, e.g.
  // ServerDomainMap.Add('CORP.ABC.COM', 'ABCCORP') change conversion for previuos 
  // example to 'ABCCORP\user1'
  // - use only if automatic conversion (truncate on first dot) do it wrong
  ServerDomainMap: TSynNameValue;

#43 Re: mORMot Framework » Windows authentication on the server » 2018-06-13 09:41:37

I suppose it is hard to automatically convert names, so it could be useful to introduce some "dictionary" and register name pairs while bootstrapping.

NT4 (or NetBIOS) domain names are outdated now, so I think we can choose a different way: the fully qualified domain name.

Currently used names:

DOMAIN\user1
ABCCORP\user1

New names:

DOMAIN.TLD\user1
CORP.ABC.COM.UA\user1

For backward compatibility we must add ServerForceShortDomain.

#44 Re: mORMot Framework » Windows authentication on the server » 2018-06-06 08:46:10

2mpv

To use same value for TSQLAuthUser.LogonName on all platforms user name changed from 'username@MYDOMAIN.TLD' to 'MYDOMAIN\username'.
You used in previous version 'username@MYDOMAIN.TLD'.

So for you added function ServerForceNativeUserName. If you do not use GSSAPI in production yet, it may be removed.

#45 Re: mORMot Framework » Windows authentication on the server » 2018-06-06 07:44:37

ab wrote:

1. We could simply identify and compute the expected user name on Linux server,  and convert 'domain\user1' to 'user1@DOMAIN.TLD' on this platform.
I mean, use the Windows convention on the client side on all platforms.

I added user name conversion - 'domain\user1' used on all platforms.

For clarification: our goal is to store same value in TSQLAuthUser.LogonName, and no need to modify database when server moved from Windows to Linux or vice versa.

ab wrote:

2. I'm not sure I understand this point.

On Windows we can omit service SPN in client at all. In that case NTLM is used and client not check service identity - all works fine.

On Linux if I omit service SPN then GSSAPI return error 'A required input parameter could not be read'.
And we must always specify SPN in aPassword parameter for SetUser.

But there exists other option: authenticate with manually specified domain user name and clear text password.
In this case aPassword (in SetUser) used for password, so no space for SPN.
Function ClientForceSPN was added for that use case.

ab wrote:

4. I'm not sure I understand this point.

Browsers can create SPN from hostname automatically.

After some investigation I realized that it is difficult: we need DNS request, consider the presence of a proxy, standard/non-standerd port, case sensivity on Linux, and so on (chromium, if someone is interested).
it's easier to specify the correct SPN manually.

P.S.
mpv, waiting for your opinion.

#46 Re: mORMot Framework » Windows authentication on the server » 2018-06-05 08:38:44

https://github.com/synopse/mORMot/pull/117

This is a feature-rich GSSAPI authentication implementation.

Can work (I hope) in any direction (with proper configuration):
Windows Client -> Windows Server
Windows Client -> Linux Server
Linux Client -> Windows Server
Linux Client -> Linux Server
Windows Browser -> Windows Server
Windows Browser -> Linux Server
Linux Browser -> Windows Server
Linux Browser -> Linux Server

Of course, we need to test it (especially on Linux).

Indeed, there are still some problems, perhaps a discussion is required:

1. Different user names: 'domain\user1' for Windows and 'user1@DOMAIN.TLD' on Linux.
We can use 'user1@DOMAIN.TLD' on Windows too, but this is backward incompatible and '\' is really rare used for average LogonName, but '@' is commonly used.

2. No space for SPN if we use authentification with domain username and password, and new function ClientForceSPN introduced for this.

3. in mORMot.pas there is call to LoadGSSAPI, since dynamically load library in server thread pool is a bad idea (race condition).

4. Linux client can't work without SPN and it is required. In theory, we can create SPN from server hostname, as browser did it.

#47 Re: mORMot Framework » Windows authentication on the server » 2018-05-30 10:00:42

Also, unit finalization code wrong:

type
  PGSSAPIFunctions = ^TGSSAPIFunctions;
  TGSSAPIFunctions = record ... end;
var
  GSSAPI: PGSSAPIFunctions;
begin
  New(GSSAPI);
  ...
  FreeAndNil(GSSAPI); // FreeAndNil calls TObject destructor
end;

So, finalization code should be:

finalization
  if GSSAPI<>nil then begin
    FreeLibrary(GSSAPI^.gsslib);
    Dispose(GSSAPI);
    GSSAPI := nil;
  end;
end.

#48 Re: mORMot Framework » Windows authentication on the server » 2018-05-30 09:42:38

My test environment: Ubuntu 18.04 x86_64, NewPascal 1.0.55 (FPC 3.1.1, Lazarus 1.9.0).

When I run test app I get SIGSEGV on line:

PPointer(@gss_indicate_mechs)^ := GetProcAddress(handle, 'gss_indicate_mechs');

Looks like as this statement does not work as expected under FPC. So I change it to:

gss_indicate_mechs := GetProcAddress(handle, 'gss_indicate_mechs');

And now statement works.

On assembler we see an error: unnecessary level of indirection.
fpc_error1.png
I'm not familiar with FPC and I do not know how to correctly fix this error.

Сontinue testing...

#49 Re: mORMot Framework » Windows authentication on the server » 2018-05-11 09:18:56

I think it is better to do so:
1. Add SynGSSAPI.pas as linux counterpart to SynSSPI.pas
2. Add ifdef Windows/Linux to SynSSPIAuth.pas and implement authentication using SynSSPI.pas or SynGSSAPI.pas
3. May be rename SynSSPIAuth.pas to SynDomainAuth.pas or something else
4. Do not touch mORMot.pas

Some time ago I use krb5 library on linux, so I think I can help implementing Kerberos on linux.

And I recommend using Dovecot auth as reference:
https://github.com/dovecot/core/blob/ma … h-gssapi.c

Board footer

Powered by FluxBB