====== 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
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)
> 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 =====
print('eigener Skriptname wird ausgegeben:')
print(arg[0])
print()
print('erstes Argument wird ausgegeben:')
print(arg[1])
print()
print('alle Argumente werden ausgegeben:')
print(...)
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 1 2 3 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]]
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()
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]]
$HTTP["host"] =~ "10.10.69.69" {
magnet.attract-physical-path-to = ( "/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()
> 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''
# 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" )
}
-- 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
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.