Benutzer-Werkzeuge

Webseiten-Werkzeuge


lua

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen RevisionVorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
lua [2016-10-18 09:51:11] – [LighttpD + Lua] manfredlua [2017-05-19 14:03:15] (aktuell) manfred
Zeile 1: Zeile 1:
 +====== Lua ======
 +
 +  * [[http://lua.coders-online.net/35]]
 +  * [[https://www.tutorialspoint.com/lua/lua_file_io.htm]]
 +  * [[https://de.wikipedia.org/wiki/Lua]]
 +  * [[http://lua.coders-online.net/]] - deutsche Lua-Seite
 +  * **[[http://www.pro-linux.de/news/1/22838/netbsd-70-freigegeben.html|Seit NetBSD 7 ist der Kernel in der Lage, Lua-Code dank eines integrierten, als Treiber realisierten Interpreters, direkt auszuführen.]] - Vorbild war offenbar die wenig bekannte Lua-Engine [[https://github.com/lunatik-ng/lunatik-ng|Lunatik]] für den Linux-Kernel.**
 +
 +Lua wurde 1993 von der Computer Graphics Technology Group der Päpstlichen Katholischen Universität von Rio de Janeiro in Brasilien entwickelt. Lua ist freie Software und wurde bis zur Version 4 unter einer eigenen BSD-Lizenz veröffentlicht, seit Version 5 unter der MIT-Lizenz.
 +
 +Lua kann sowohl zur Erstellung eigenständiger Programme verwendet werden als auch als eingebettete Sprache dienen.
 +
 +
 +===== Einführung =====
 +
 +  * [[https://www.lua.org/manual/5.1/]]
 +  * [[https://wiki.multitheftauto.com/wiki/DE/Lua_Tutorial]]
 +  * [[http://lua.lickert.net/function/]]
 +  * [[https://www.lua.org/manual/5.1/manual.html#pdf-io.popen]]
 +  * [[http://lua-users.org/wiki/OsLibraryTutorial]]
 +  * [[http://lua.lickert.net/operators/]]
 +
 +
 +====  ====
 +
 +  * [[https://www.gammon.com.au/scripts/doc.php?lua=os.execute]] - ein Programm aus LUA raus in einer Shell ausführen
 +
 +<file lua lua_start.lua>
 +local parameter = "root";
 +print("Parameter: ", parameter)
 +
 +local pfaddatei = ("/usr/bin/id " .. parameter)
 +print("Kammando: ", pfaddatei)
 +
 +datei = assert (io.popen (pfaddatei))
 +print ("Temp-Datei-Händler: ", datei)
 +
 +ausgabe = datei:read ("*l") -- read one line
 +print ("Rückgabewert: ", ausgabe)
 +
 +for line in io.lines(pfaddatei) do print (line) end
 +
 +local myFile = io.open( pfaddatei, "r+b" )
 +dateigroesse = (myFile:seek("end"))
 +print ("die Datei ist so groß: " .. dateigroesse)
 +</file>
 +
 +  > lua lua_start.lua
 +  Parameter:      root
 +  Kammando:       /usr/bin/id root
 +  Temp-Datei-Händler:     file (0x1657270)
 +  Rückgabewert:   uid=0(root) gid=0(root) groups=0(root)
 +
 +
 +===== Argumentenübergabe =====
 +
 +<file lua /tmp/test_args.lua>
 +print('eigener Skriptname wird ausgegeben:')
 +print(arg[0])
 +print()
 +print('erstes Argument wird ausgegeben:')
 +print(arg[1])
 +print()
 +print('alle Argumente werden ausgegeben:')
 +print(...)
 +</file>
 +
 +Beispiel:
 +  > lua /tmp/test_args.lua 0 1 2 3 4
 +  eigener Skriptname wird ausgegeben:
 +  /tmp/test.lua
 +  
 +  erstes Argument wird ausgegeben:
 +  0
 +  
 +  alle Argumente werden ausgegeben:
 +  0                         4
 +
 +
 +===== Datenbankzugriff =====
 +
 +  * [[https://keplerproject.github.io/luasql/examples.html]]
 +  * [[https://keplerproject.github.io/luasql/manual.html#mysql_extensions]]
 +    - ''env:connect(sourcename[,username[,password[,hostname[,port]]]])''
 +      * [[https://keplerproject.github.io/luasql/manual.html#environment_object]]
 +      * [[https://keplerproject.github.io/luasql/manual.html#connection_object]]
 +    - ''conn:escape(str)''
 +      * [[http://dev.mysql.com/doc/refman/5.7/en/mysql-real-escape-string.html]]
 +    - ''conn:getlastautoid()''
 +    - ''cur:numrows()''
 +      * [[https://keplerproject.github.io/luasql/manual.html#cursor_object]]
 +
 +<file lua /tmp/test_db.lua>
 +local dbConf = {}
 +dbConf.database = 'mitglieder'
 +dbConf.username = 'fritz'
 +dbConf.passwort = 'geheim'
 +dbConf.hostname = '10.234.123.45'
 +dbConf.port = "3306"
 +
 +require("mime")
 +luasql = require("luasql.mysql")
 +
 +local env = assert(luasql.mysql())
 +local con = assert(env:connect ( dbConf.database, dbConf.username, dbConf.passwort, dbConf.hostname, dbConf.port ))
 +
 +
 +function rows (connection, sql_statement)
 +  local cursor = assert (connection:execute (sql_statement))
 +  return function ()
 +    return cursor:fetch()
 +  end 
 +end
 +
 +
 +for id, name, address in rows (con, "select * from dealer_logins") do
 +        -- "id" und "name" sind Spaltennamen in der Tabelle
 +        print (string.format ("%s: %s", id, name))
 +end
 +
 +
 +con:close()
 +env:close()
 +</file>
 +
 +ausführen
 +  > lua /tmp/test_db.lua
 +
 +
 +===== LighttpD + Lua =====
 +
 +  * [[https://www.innerfence.com/blog/tag/lua/]]
 +  * [[https://redmine.lighttpd.net/projects/lighttpd/wiki/AbsoLUAtion]]
 +
 +Voraussetzungen:
 +  * mod_magnet
 +  * Lua (v5.1; lighttpd 1.4.40+ should also support v5.2 and v5.3) [[http://www.lua.org]]
 +
 +<file bash /etc/lighttpd/conf-enabled/99-lua.conf>
 +$HTTP["host"] =~ "10.10.69.69" {
 +                magnet.attract-physical-path-to = ( "/etc/lighttpd/test.lua" )
 +}
 +</file>
 +
 +<file lua /etc/lighttpd/test.lua>
 +datei = io.open("/tmp/lua_env.txt","w")
 +datei:write("uri.authority: ", string.format('%s', lighty.env["uri.authority"]), "\n")
 +datei:write("uri.path: ", string.format('%s', lighty.env["uri.path"]), "\n")
 +datei:write("uri.path-raw: ", string.format('%s', lighty.env["uri.path-raw"]), "\n")
 +datei:write("uri.scheme: ", string.format('%s', lighty.env["uri.scheme"]), "\n")
 +datei:write("physical.path: ", string.format('%s', lighty.env["physical.path"]), "\n")
 +datei:write("physical.rel-path: ", string.format('%s', lighty.env["physical.rel-path"]), "\n")
 +datei:write("physical.doc-root: ", string.format('%s', lighty.env["physical.doc-root"]), "\n")
 +datei:close()
 +</file>
 +
 +  > cat /tmp/lua_env.txt
 +  uri.authority: 10.123.234.56
 +  uri.path: /test.php
 +  uri.path-raw: /test.php
 +  uri.scheme: https
 +  physical.path: /var/www/test.php
 +  physical.rel-path: /test.php
 +  physical.doc-root: /var/www/
 +
 +
 +==== MySQL-Auth mit LighttpD ====
 +
 +Leider gibt es für LighttpD kein Modul um die Passwortabfrage auf eine DB zu realisieren, wie man es vom Apache kennt. Um eine derartige Funktionalität in LighttpD umzusetzten, muss man ein entsprechendes LUA-Skript einbinden.
 +
 +  * [[https://redmine.lighttpd.net/projects/lighttpd/wiki/AbsoLUAtion#Do-basic-HTTP-Auth-against-a-MySQL-DBTable]]
 +
 +__Die Dateien, die Passwörter enthalten, dürfen nicht für die Welt lesbar sein!__
 +  > chown 33:33 /etc/lighttpd/sha512crypt.php /etc/lighttpd/mysql_auth.lua
 +  > chmod 0640 /etc/lighttpd/sha512crypt.php /etc/lighttpd/mysql_auth.lua
 +
 +Die individuellen Daten sehen wie folgt aus, sie können (und müssen) den persönlichen Gegebenheiten angepasst werden:
 +  * **zu schützender Web-Server:** ''10.10.69.69''
 +  * **Datenbank-Server mit den Passwörtern:** ''10.123.45.67''
 +  * **Datenbank-Port:** ''3306''
 +  * **Passwort-Datenbank-Name:** ''pwdb''
 +  * **Passwort-Tabellenname in der Passwort-Datenbank:** ''pwtab''
 +  * **es müssen mindestens diese beiden Spalten in der Tabelle vorhanden sein:** ''name'' und ''passwort''
 +  * **Passwort-Verschlüsselung:** ''SHA512''
 +  * **das "Salz" für die Verschlüsselung:** ''tuqu7Cua_ox1jieW''
 +
 +<file lighttpd /etc/lighttpd/conf-enabled/20-mysql_auth.conf>
 +# bei Zugriffen auf diesen Web-Server soll das LUA-Skript aktiviert werden
 +$HTTP["host"] =~ "10.10.69.69" {
 +                magnet.attract-physical-path-to = ( "/etc/lighttpd/mysql_auth.lua" )
 +}
 +</file>
 +
 +<file lua /etc/lighttpd/mysql_auth.lua>
 +-- nur "/geheim.php" soll passwortgeschützt sein
 +if ( string.format('%s', lighty.env["uri.path"]) == "/geheim.php" ) then
 +
 +-- Passwörter dürfen nur per https eingegeben werden
 +if (lighty.env["uri.scheme"] == "http") then
 +    lighty.header["Location"] = "https://" .. lighty.env["uri.authority"] .. lighty.env["request.uri"]
 +    return 302
 +end
 +
 +--[[
 +    Config Variables
 +]]
 +local dbConf = {}
 +dbConf.database = 'pwdb'
 +dbConf.username = 'fritz'
 +dbConf.passwort = 'geheim'
 +dbConf.hostname = '10.123.45.67'
 +dbConf.port = "3306"
 +
 +--[[
 +    Requires
 +]]
 +
 +-- Debian package: liblua5.1-socket2
 +
 +-- required for Base64 De-/encoding. See: http://w3.impa.br/~diego/software/luasocket/home.html
 +require("mime")
 +
 +-- Debian package: liblua5.1-sql-mysql-2
 +
 +-- Lua Mysql Driver
 +luasql = require("luasql.mysql")
 +
 +--[[
 +    Function to send HTTP-Auth request
 +]]
 +
 +function doAuth()
 +    lighty.header["WWW-Authenticate"] = string.format('Basic realm="%s"', lighty.env["uri.authority"])
 +    return 401
 +end
 +
 +--[[
 +    Function to check Auth Creds against MySQL Database
 +]]
 +local env = assert(luasql.mysql())
 +local con = assert(env:connect (
 +        dbConf.database
 +        ,dbConf.username
 +        ,dbConf.passwort
 +        ,dbConf.hostname
 +        ,dbConf.port
 +))
 +
 +function checkAuthMySQL(user,pass)
 +        local res = con:execute(string.format([[
 +                SELECT *
 +                FROM `pwtab`
 +                WHERE `name` = '%s'
 +                AND `passwort` = '%s'
 +                ]], user, pass)
 +        )
 +
 +        -- Die Tabelle wir in ein Array gespeichert
 +        local row = res:fetch ({}, "a")
 +
 +        -- print(type(row))
 +
 +
 +        -- close everything
 +        -- res:close()  -- already closed because all the result set was consumed
 +        con:close()
 +        -- env:close()
 +
 +
 +        if (not row) then
 +                return false
 +        else
 +                lighty.req_env['REMOTE_USER'] = user
 +                return true
 +        end
 +end
 +
 +
 +-- MAIN
 +
 +--[[
 +    Check for Authorization Header
 +    and force Basic Auth if not set.
 +]]
 +
 +if (not lighty.request.Authorization) then
 +    return doAuth()
 +end
 +
 +--[[
 +    Header found: check string for "Basic" and base64 encoded username & password
 +    - upb = User Password Base64 encoded
 +]]
 +_, _, upb = string.find(lighty.request.Authorization, "^Basic%s+(.+)$")
 +up = mime.unb64(upb) -- Base64 Decode
 +_, _, username, passwort = string.find(up, "^(.+):(.+)$") -- split by ":" to get username and password supplied
 +
 +
 +-- =============================================================================
 +-- In der DB steht das Passwort nicht im klartext drin, sondern verschlüsselt
 +-- deshalb muss auch der Passwort-Hash und nicht das Passwort verglichen werden.
 +--
 +-- hier wird aus dem Passwort der Passwort-Hash generiert
 +--
 +
 +local kommando = ("/usr/bin/php /etc/lighttpd/sha512crypt.php " .. passwort)
 +ausgabe = assert (io.popen (kommando))
 +pwhash = ausgabe:read ("*l") -- read one line
 +
 +-- =============================================================================
 +
 +if (not checkAuthMySQL(username, pwhash)) then
 +        return doAuth()
 +end
 +
 +
 +end
 +
 +-- return nothing to proceed normal operation
 +return
 +
 +</file>
 +
 +Leider gibt es nur für eine [[in LUA native SHA256-Verschlüsselung|SHA256-Verschlüsselung]] eine native LUA-Umsetzung.
 +Für SHA512 müssen wir uns eines externen Programmes (in diesem Fall ein PHP-Skript) bedienen.
 +
 +<file php /etc/lighttpd/sha512crypt.php>
 +<?php
 +$salt = 'tuqu7Cua_ox1jieW';
 +echo hash('sha512', $salt . $argv[1]);
 +?>
 +</file>