AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Named Pipes zwischen Service und eingeschränktem Programm
Thema durchsuchen
Ansicht
Themen-Optionen

Named Pipes zwischen Service und eingeschränktem Programm

Ein Thema von CodeX · begonnen am 30. Aug 2008 · letzter Beitrag vom 6. Nov 2008
Antwort Antwort
Seite 2 von 3     12 3      
Fridolin Walther

Registriert seit: 11. Mai 2008
Ort: Kühlungsborn
446 Beiträge
 
Delphi 2009 Professional
 
#11

Re: Named Pipes zwischen Service und eingeschränktem Program

  Alt 30. Aug 2008, 15:13
Delphi-Quellcode:
program pipeserver;

{$APPTYPE CONSOLE}

uses
  jwawinbase, jwawintype, jwawinnt, jwaaccctrl, jwaaclapi, jwawinerror, sysutils;

function InstanceThread(PipeHandle : dword) : dword; stdcall;
var
  Value : dword;
  tmp : dword;
begin
  result := 0;

  ReadFile(PipeHandle, @Value, 4, @tmp, nil);
  WriteFile(PipeHandle, @Value, 4, @tmp, nil);

  FlushFileBuffers(PipeHandle);
  DisconnectNamedPipe(PipeHandle);
  CloseHandle(PipeHandle);
end;

function ServerThread(unused : dword) : dword; stdcall;
const
  BUFSIZE = 4;
var
  PipeHandle : dword;
  Connected : boolean;
  SA : LPSECURITY_ATTRIBUTES;
  ACL : PACL;
  Group : TRUSTEE;
  EA : PEXPLICIT_ACCESS;
  SD : PSECURITY_DESCRIPTOR;
  ACL_SIZE : ACL_SIZE_INFORMATION;
  tmp : dword;
begin
  Group.MultipleTrusteeOperation := NO_MULTIPLE_TRUSTEE;
  Group.pMultipleTrustee := nil;
  Group.ptstrName := 'Jeder';
  Group.TrusteeForm := TRUSTEE_IS_NAME;
  Group.TrusteeType := TRUSTEE_IS_GROUP;

  new(EA);
  EA^.grfAccessMode := GRANT_ACCESS;
  EA^.grfAccessPermissions := GENERIC_READ or GENERIC_WRITE;
  EA^.grfInheritance := NO_INHERITANCE;
  EA^.Trustee := group;

  SetEntriesInAcl(1, EA, nil, ACL);
  GetAclInformation(ACL, @ACL_SIZE, sizeof(ACL_SIZE), AclSizeInformation);
  getmem(SD, SECURITY_DESCRIPTOR_MIN_LENGTH + ACL_SIZE.AclBytesFree + ACL_SIZE.AclBytesInUse);
  InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION);
  SetSecurityDescriptorDacl(sd, TRUE, ACL, FALSE);

  new(SA);
  sa^.bInheritHandle := FALSE;
  sa^.lpSecurityDescriptor := sd;
  sa^.nLength := sizeof(sa);

  while true do
    begin
      PipeHandle := CreateNamedPipeW('\\.\pipe\demopipe', PIPE_ACCESS_DUPLEX,
                                     PIPE_TYPE_MESSAGE or PIPE_READMODE_MESSAGE or
                                     PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, BUFSIZE,
                                     BUFSIZE, INFINITE, SA);

      if PipeHandle = INVALID_HANDLE_VALUE then
        begin
          sleep(100);
          continue;
        end;

      Connected := ConnectNamedPipe(PipeHandle, nil)
                   or (GetLastError = ERROR_PIPE_CONNECTED);

      if Connected then
        begin
          tmp := CreateThread(nil, 0, @InstanceThread,
                                       Pointer(PipeHandle), 0, nil);
          if tmp = 0 then
            begin
              DisconnectNamedPipe(PipeHandle);
              CloseHandle(PipeHandle);
              continue;
            end else
              CloseHandle(tmp);
        end else
          CloseHandle(PipeHandle);
  end;

  LocalFree(cardinal(ACL));
  freemem(SD);
  dispose(EA);
end;

var
  tmp : dword;
begin
  write('Starting ServerThread: ');
  tmp := CreateThread(nil, 0, @ServerThread, nil, 0, nil);
  writeln(tmp <> 0);
  CloseHandle(tmp);
  readln;
end.
Ist ein kleiner Pipe Server, der eine Pipe mit einer DACL die Jedem im System explizit Lese und Schreibrechte erlaubt erstellt.
Fridolin Walther
  Mit Zitat antworten Zitat
CodeX

Registriert seit: 30. Okt 2004
475 Beiträge
 
Delphi 12 Athens
 
#12

Re: Named Pipes zwischen Service und eingeschränktem Program

  Alt 30. Aug 2008, 15:21
Danke!
Sieht recht kompliziert aus. Ich habe parallel hier im Forum noch nach dem Stichwort gesucht und diesen Thread hier gefunden.
Tun es die paar Zeilen, um FSA zu bestimmen, auch? Oder gibt es irgendwelche Bedenken?

Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
var
   FSA : SECURITY_ATTRIBUTES;
   FSD : SECURITY_DESCRIPTOR;
   pch1: shortstring;
begin
   InitializeSecurityDescriptor(@FSD, SECURITY_DESCRIPTOR_REVISION);
   SetSecurityDescriptorDacl(@FSD, True, nil, False);
   FSA.lpSecurityDescriptor := @FSD;
   FSA.nLength := sizeof(SECURITY_ATTRIBUTES);
   FSA.bInheritHandle := True;

   Pipe:= CreateNamedPipe(PChar('\\.\pipe\<test>'),
                          PIPE_ACCESS_DUPLEX or FILE_FLAG_WRITE_THROUGH,
                          PIPE_TYPE_MESSAGE or PIPE_READMODE_MESSAGE or PIPE_NOWAIT,
                          PIPE_UNLIMITED_INSTANCES,
                          1024,
                          1024,
                          50,
                          @FSA);
end;
  Mit Zitat antworten Zitat
Fridolin Walther

Registriert seit: 11. Mai 2008
Ort: Kühlungsborn
446 Beiträge
 
Delphi 2009 Professional
 
#13

Re: Named Pipes zwischen Service und eingeschränktem Program

  Alt 30. Aug 2008, 15:27
Funktioniert genauso. Allerdings solltest Du Dir bewusst sein, das alles und jeder dann auf die Pipe zugreifen kann - auch übers Netzwerk und ohne Authentifizierung!
Fridolin Walther
  Mit Zitat antworten Zitat
CodeX

Registriert seit: 30. Okt 2004
475 Beiträge
 
Delphi 12 Athens
 
#14

Re: Named Pipes zwischen Service und eingeschränktem Program

  Alt 30. Aug 2008, 16:05
Hm, also mein Service prüft den Sender der Nachricht auf seine Signatur und agiert nur dann, wenn es sich um meine Signatur handelt.
Dennoch wäre es wahrscheinlich nicht verkehrt, die beiden Punkte Netzwerk und Authentifizierung in den Code einzubeziehen.

Ich habe Deinen Code nun genauer angeschaut. Ich verstehe zwar nicht alles davon, aber die Zeile Group.ptstrName := 'Jeder'; macht mich stutzig. Die starre Angabe, würde dann doch nur auf deutschen Betriebssystemen funktionieren, oder? Ich nehme an, dass es nicht einfach einen Flag-Wert gibt, der nur lokal angemeldete Benutzer zulässt?
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#15

Re: Named Pipes zwischen Service und eingeschränktem Program

  Alt 30. Aug 2008, 16:09
Mit der TRUSTEE-Struktur kann man Gruppen oder Benutzer nicht nur per Name, sondern auch per SID angeben. *klick* Die SID der eingebauten Gruppen ist unabhängig von der Sprache.
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
Fridolin Walther

Registriert seit: 11. Mai 2008
Ort: Kühlungsborn
446 Beiträge
 
Delphi 2009 Professional
 
#16

Re: Named Pipes zwischen Service und eingeschränktem Program

  Alt 30. Aug 2008, 16:19
Nunja, das war Code aus einem kleinen Beispiel von mir, wie man eine Pipe erstellt auf die nur Mitglieder einer bestimmten Gruppe Zugriff haben. Für Deine Zwecke wäre es wahrscheinlich besser den Zugriff an einen Well Known SID zu koppeln. Der Code würde dann so aussehen:

Delphi-Quellcode:
program pipeserver;

{$APPTYPE CONSOLE}

uses
  jwawinbase, jwawintype, jwawinnt, jwaaccctrl, jwaaclapi, jwawinerror, sysutils;

function InstanceThread(PipeHandle : dword) : dword; stdcall;
var
  Value : dword;
  tmp : dword;
begin
  result := 0;

  ReadFile(PipeHandle, @Value, 4, @tmp, nil);
  WriteFile(PipeHandle, @Value, 4, @tmp, nil);

  FlushFileBuffers(PipeHandle);
  DisconnectNamedPipe(PipeHandle);
  CloseHandle(PipeHandle);
end;

function ServerThread(unused : dword) : dword; stdcall;
const
  BUFSIZE = 4;
var
  PipeHandle : dword;
  Connected : boolean;
  SA : LPSECURITY_ATTRIBUTES;
  ACL : PACL;
  Group : TRUSTEE;
  EA : PEXPLICIT_ACCESS;
  SD : PSECURITY_DESCRIPTOR;
  ACL_SIZE : ACL_SIZE_INFORMATION;
  WellKnownSID : PSID;
  tmp : dword;
begin
  tmp := SECURITY_MAX_SID_SIZE;
  GetMem(WellKnownSID, tmp);
  CreateWellKnownSid(WinWorldSid, nil, WellKnownSID, tmp);

  Group.MultipleTrusteeOperation := NO_MULTIPLE_TRUSTEE;
  Group.pMultipleTrustee := nil;
  Group.ptstrName := Pointer(WellKnownSID);
  Group.TrusteeForm := TRUSTEE_IS_SID;
  Group.TrusteeType := TRUSTEE_IS_WELL_KNOWN_GROUP;

  new(EA);
  EA^.grfAccessMode := GRANT_ACCESS;
  EA^.grfAccessPermissions := GENERIC_READ or GENERIC_WRITE;
  EA^.grfInheritance := NO_INHERITANCE;
  EA^.Trustee := group;

  SetEntriesInAcl(1, EA, nil, ACL);
  GetAclInformation(ACL, @ACL_SIZE, sizeof(ACL_SIZE), AclSizeInformation);
  getmem(SD, SECURITY_DESCRIPTOR_MIN_LENGTH + ACL_SIZE.AclBytesFree + ACL_SIZE.AclBytesInUse);
  InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION);
  SetSecurityDescriptorDacl(sd, TRUE, ACL, FALSE);

  new(SA);
  sa^.bInheritHandle := FALSE;
  sa^.lpSecurityDescriptor := sd;
  sa^.nLength := sizeof(sa);

  while true do
    begin
      PipeHandle := CreateNamedPipeW('\\.\pipe\demopipe', PIPE_ACCESS_DUPLEX,
                                     PIPE_TYPE_MESSAGE or PIPE_READMODE_MESSAGE or
                                     PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, BUFSIZE,
                                     BUFSIZE, INFINITE, SA);

      if PipeHandle = INVALID_HANDLE_VALUE then
        begin
          sleep(100);
          continue;
        end;

      Connected := ConnectNamedPipe(PipeHandle, nil)
                   or (GetLastError = ERROR_PIPE_CONNECTED);

      if Connected then
        begin
          tmp := CreateThread(nil, 0, @InstanceThread,
                                       Pointer(PipeHandle), 0, nil);
          if tmp = 0 then
            begin
              DisconnectNamedPipe(PipeHandle);
              CloseHandle(PipeHandle);
              continue;
            end else
              CloseHandle(tmp);
        end else
          CloseHandle(PipeHandle);
  end;

  LocalFree(cardinal(ACL));
  freemem(SD);
  freemem(WellKnownSID);
  dispose(EA);
end;

var
  tmp : dword;
begin
  write('Starting ServerThread: ');
  tmp := CreateThread(nil, 0, @ServerThread, nil, 0, nil);
  writeln(tmp <> 0);
  CloseHandle(tmp);
  readln;
end.
Eine Liste der Well Known SIDs gibts hier: http://msdn.microsoft.com/en-us/library/aa379650(VS.85).aspx
In Deinem Falle wäre wohl WinLocalSid nützlich.

Man kann den Code übrigens noch stark vereinfachen indem man die JWSCL benutzt. Allerdings ist mir die JWSCL für meinen Geschmack zu viel Overhead.
Fridolin Walther
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#17

Re: Named Pipes zwischen Service und eingeschränktem Program

  Alt 30. Aug 2008, 16:23
Wäre es hier nicht klüger, den Speicher für WellKnownSID auf dem Stack zu reservieren?
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
Fridolin Walther

Registriert seit: 11. Mai 2008
Ort: Kühlungsborn
446 Beiträge
 
Delphi 2009 Professional
 
#18

Re: Named Pipes zwischen Service und eingeschränktem Program

  Alt 30. Aug 2008, 16:25
Welchen Vorteil erhoffst Du Dir dadurch?
Fridolin Walther
  Mit Zitat antworten Zitat
CodeX

Registriert seit: 30. Okt 2004
475 Beiträge
 
Delphi 12 Athens
 
#19

Re: Named Pipes zwischen Service und eingeschränktem Program

  Alt 30. Aug 2008, 16:26
Zitat von 0xF30FC7:
Man kann den Code übrigens noch stark vereinfachen indem man die JWSCL benutzt.
Ich bin ganz Ohr!
Da ich die JWSCL so oder so bereits eingebunden habe, würd ich auch gern den vereinfachten Code nehmen.

Zitat von 0xF30FC7:
Allerdings ist mir die JWSCL für meinen Geschmack zu viel Overhead.
Ja, stimmt leider. Hat mich auch Überwindung gekostet, mich letztlich darauf festzulegen. Aber gut, die Arbeitsersparnis wars dann doch Wert.
  Mit Zitat antworten Zitat
Apollonius

Registriert seit: 16. Apr 2007
2.325 Beiträge
 
Turbo Delphi für Win32
 
#20

Re: Named Pipes zwischen Service und eingeschränktem Program

  Alt 30. Aug 2008, 16:40
@0xF30FC7: Ich finde einfach, dass man den Memory Manager nicht bemühen sollte, wenn der Stack es genauso tut, denn er ist in jedem Fall langsamer und hat einen nicht zu vernachlässigenden Speicher-Overhead.
Das gleiche gilt für EA. Bei SD würde ich allerdings auch den MM nehmen, da du die Größe nicht im Voraus weißt.
Wer erweist der Welt einen Dienst und findet ein gutes Synonym für "Pointer"?
"An interface pointer is a pointer to a pointer. This pointer points to an array of pointers, each of which points to an interface function."
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 3     12 3      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:04 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz