FPHttpServer and linux auth lazarus / 38-Networking and Web Programming ---------------------------------------------------------------------- GreyCrazyWolf · 2023-09-13 06:54 Hello all! I am creating an HTTP server application using FPHttpServer and I have a question, how can I perform authorization by an existing Linux user? I can verify the existence of a user by login as follows Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i function TMySvr.CheckLinuxUser(AUserName, APassword: String): Boolean;var  Pwd: PPasswd;begin  Result := False;   Pwd := fpgetpwnam(PChar(AUserName));   if Pwd <> nil then  begin     // if Pwd not nil - user exists     // Now, need to check the password is correct  :-\  end;end; ---------------------------------------------------------------------- Leledumbo · 2023-09-13 10:46 There's no really an easy way as there's no direct single API for that. The non-programmatic way is more or less like this: Code: Bash  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i $ sudo grep $USER /etc/shadowThis will spit out current user's shadow entry (note the sudo, this file is protected from non-root access by default), it should be in the form of: Code: [Select]:$$$:Now ask OpenSSL for help: Code: Bash  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i $ openssl passwd - -salt You will be prompted for password, input the user's password. The result should be the same as above. Bypassing the sudo without compromising security is something I haven't found a way out for. OpenSSL hashing method might be convertible with something from fcl-hash, but I haven't tried finding yet. ---------------------------------------------------------------------- PierceNg · 2023-09-13 13:20 Quote from: GreyCrazyWolf on September 13, 2023, 08:54:32 amHello all! I am creating an HTTP server application using FPHttpServer and I have a question, how can I perform authorization by an existing Linux user? PAM - Pluggable Authentication Modules See https://linux.die.net/man/8/pam_unix: QuoteThis is the standard Unix authentication module. It uses standard calls from the system's libraries to retrieve and set account information as well as authentication. Usually this is obtained from the /etc/passwd and the /etc/shadow file as well if shadow is enabled. Then see Apache mod_pam and Nginx mod_pam: - https://github.com/adelton/mod_authnz_pam - https://github.com/sto/ngx_http_auth_pam_module - https://serverfault.com/questions/372719/how-to-use-nginx-pam-module Also, there's this forum thread: - https://forum.lazarus.freepascal.org/index.php?topic=58386.0 ---------------------------------------------------------------------- GreyCrazyWolf · 2023-09-13 16:34 Quote from: Leledumbo on September 13, 2023, 12:46:23 pmThere's no really an easy way as there's no direct single API for that. Thank you very much. So far I have rewritten the function in this way Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i function TMySvr.CheckLinuxUser(AUserName, APassword: String): Boolean;var  Pwd        : PPasswd;  outString    : String;  outArrayF    : TStringArray;  outArrayS    : TStringArray;  outArrayT    : TStringArray;begin  Result := False;   // Retrieve user information from the Linux user database  Pwd := fpgetpwnam(PChar(AUserName));  if Pwd <> nil then     begin       if RunCommand(Format('sudo grep %s /etc/shadow', [AUserName]), outString) then         begin            outArrayF := outString.Split(':');              outArrayS := outArrayF[1].Split('$');              if RunCommand(Format('openssl passwd -%s -salt %s %s', [outArrayS[1], outArrayS[2], APassword]), outString) then                 begin                      outArrayT := outString.Replace(#10, '').Split('$');                      Result :=  outArrayS[3] = outArrayT[3];                 end;         end;     end;end;           It works fine on the test vbox Part can be removed after debugging Quote from: PierceNg on September 13, 2023, 03:20:44 pmPAM - Pluggable Authentication Modules Thank you very much. I'll try to use ---------------------------------------------------------------------- colo · 2023-09-13 19:14 Be aware that this will be catastrophically exploitable if/when someone feeds carefully crafted data for AUserName and/or APassword into your program. If I were you, I would just not use the system account database via PAM for storing and retrieving credential data, but use another (custom) data source for that.