diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1377554 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.swp diff --git a/Makefile b/Makefile index 10c6c27..ca0612f 100644 --- a/Makefile +++ b/Makefile @@ -4,14 +4,14 @@ # Path to nodemcu-uploader (https://github.com/kmpm/nodemcu-uploader) NODEMCU-UPLOADER=../nodemcu-uploader/nodemcu-uploader.py # Serial port -PORT=/dev/cu.usbserial-A602HRAZ +PORT=/dev/ttyUSB0 SPEED=9600 ###################################################################### # End of user config ###################################################################### HTTP_FILES := $(wildcard http/*) -LUA_FILES := init.lua httpserver.lua httpserver-request.lua httpserver-static.lua httpserver-header.lua httpserver-error.lua +LUA_FILES := init.lua httpserver.lua httpserver-request.lua httpserver-basicauth.lua httpserver-conf.lua httpserver-static.lua httpserver-header.lua httpserver-error.lua # Print usage usage: diff --git a/README.md b/README.md index 79ee6e8..93ddb99 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ A (very) simple web server written in Lua for the ESP8266 firmware NodeMCU. * Server-side execution of Lua scripts * Query string argument parsing * Serving .gz compressed files +* HTTP basic authentication ## How to use @@ -49,6 +50,10 @@ A (very) simple web server written in Lua for the ESP8266 firmware NodeMCU. then index.html is served. By the way, unlike most HTTP servers, nodemcu_httpserver treats the URLs in a case-sensitive manner. +4. Enable http basic authentication. + + Enable and configure http basic authentication in "httpserver-conf.lua" file. + ## How to create dynamic Lua scripts Similar to static files, upload a Lua script called "http/[name].lua where you replace [name] with your script's name. @@ -123,7 +128,6 @@ A (very) simple web server written in Lua for the ESP8266 firmware NodeMCU. ## Not supported * Other methods: HEAD, POST, PUT, DELETE, TRACE, OPTIONS, CONNECT, PATCH -* HTTP authentication * Encryption ## Notes on memory usage. diff --git a/httpserver-basicauth.lua b/httpserver-basicauth.lua new file mode 100644 index 0000000..fc295bd --- /dev/null +++ b/httpserver-basicauth.lua @@ -0,0 +1,29 @@ +-- httpserver-basicauth.lua +-- Part of nodemcu-httpserver, authenticates a user using http basic auth. +-- Author: Sam Dieck + +basicAuth = {} + +function basicAuth.authenticate(header) + conf = dofile("httpserver-conf.lc") + -- Parse basic auth http header. + -- Returns the username if header contains valid credentials, + -- nil otherwise. + local credentials_enc = header:match("Authorization: Basic ([A-Za-z0-9+/=]+)") + if not credentials_enc then + return nil + end + local credentials = dofile("b64.lc").decode(credentials_enc) + local user, pwd = credentials:match("^(.*):(.*)$") + if user ~= conf.auth.user or pwd ~= conf.auth.password then + return nil + end + print("httpserver-basicauth: User " .. user .. " authenticated.") + return user +end + +function basicAuth.authErrorHeader() + return "WWW-Authenticate: Basic realm=\"nodemcu-httpserver\"" +end + +return basicAuth diff --git a/httpserver-conf.lua b/httpserver-conf.lua new file mode 100644 index 0000000..d9e70e8 --- /dev/null +++ b/httpserver-conf.lua @@ -0,0 +1,20 @@ +-- httpserver-conf.lua +-- Part of nodemcu-httpserver, contains static configuration for httpserver. +-- Author: Sam Dieck + +conf = {} + +-- WIFI +-- FIXME use these +--wifi = {} +--wifi.essid = "Internet" +--wifi.password = "" + +-- Basic Authentication Conf +auth = {} +auth.enabled = false +auth.user = "user" +auth.password = "password" +conf.auth = auth + +return conf diff --git a/httpserver-error.lua b/httpserver-error.lua index a8dfe84..00e6bd8 100644 --- a/httpserver-error.lua +++ b/httpserver-error.lua @@ -4,11 +4,16 @@ return function (connection, args) - local function sendHeader(connection, code, errorString, mimeType) - connection:send("HTTP/1.0 " .. code .. " " .. errorString .. "\r\nServer: nodemcu-httpserver\r\nContent-Type: " .. mimeType .. "\r\nConnection: close\r\n\r\n") + local function sendHeader(connection, code, errorString, extraHeaders, mimeType) + connection:send("HTTP/1.0 " .. code .. " " .. errorString .. "\r\nServer: nodemcu-httpserver\r\nContent-Type: " .. mimeType .. "\r\n") + for i, header in ipairs(extraHeaders) do + connection:send(header .. "\r\n") + end + connection:send("connection: close\r\n\r\n") end print("Error " .. args.code .. ": " .. args.errorString) - sendHeader(connection, args.code, args.errorString, "text/html") + args.headers = args.headers or {} + sendHeader(connection, args.code, args.errorString, args.headers, "text/html") connection:send("