aboutsummaryrefslogtreecommitdiff
path: root/filters
diff refs
from: back
to: back
| flip
diff options
context:
space:
mode:
Diffstat (limited to 'filters')
-rwxr-xr-xfilters/ci-jenkins.sh58
-rwxr-xr-xfilters/commit-links.sh2
-rw-r--r--filters/email-gravatar.lua17
-rw-r--r--filters/email-libravatar.lua17
-rw-r--r--filters/file-authentication.lua359
-rw-r--r--filters/gentoo-ldap-authentication.lua76
-rwxr-xr-xfilters/html-converters/md2html104
-rw-r--r--filters/simple-authentication.lua90
-rwxr-xr-xfilters/syntax-highlighting.py45
-rwxr-xr-xfilters/syntax-highlighting.sh14
10 files changed, 90 insertions, 692 deletions
diff --git a/filters/ci-jenkins.sh b/filters/ci-jenkins.sh
deleted file mode 100755
index 842af21..0000000
--- a/filters/ci-jenkins.sh
+++ /dev/null
@@ -1,58 +0,0 @@
-#!/bin/sh
-# This script may be used with the ci-filter or repo.ci-filter setting in
-# cgitrc to hide the "ci" tab for refs which have no pipeline on a Jenkins
-# instance.
-#
-# Arguments:
-# $1 the name of the branch or tag being viewed
-# $2 "branch" or "tag"
-# $3 the ci url which the "ci" tab would redirect to
-#
-# Exit with a zero status to show the tab, non-zero to hide it. This script
-# must not write anything to standard output, as that would end up in the
-# middle of the page cgit is rendering.
-#
-# The filter is consulted while rendering every repository page, so the
-# verdict is cached on disk to keep Jenkins from being hammered, and the
-# probe is given a short timeout so that an unreachable Jenkins degrades
-# into a missing tab rather than a hanging web server.
-#
-# Set CI_NETRC to a netrc(5) file if the Jenkins instance requires
-# authentication; without it a private job answers 403 and the tab is
-# hidden even though the pipeline exists.
-
-CI_CACHE_DIR="${CI_CACHE_DIR:-/var/cache/cgit/ci-filter}"
-CI_CACHE_TTL_MINUTES="${CI_CACHE_TTL_MINUTES:-5}"
-CI_TIMEOUT="${CI_TIMEOUT:-2}"
-
-url="$3"
-test -n "$url" || exit 1
-
-# Jenkins job pages are often not readable anonymously, so query the REST
-# API rather than the page the tab points at.
-probe="$url/api/json?tree=name"
-
-key="$(printf '%s' "$url" | cksum | tr -cd '0-9')"
-cache="$CI_CACHE_DIR/$key"
-
-mkdir -p "$CI_CACHE_DIR" 2>/dev/null
-
-if test -f "$cache" &&
- test -z "$(find "$cache" -mmin "+$CI_CACHE_TTL_MINUTES" 2>/dev/null)"
-then
- exit "$(cat "$cache")"
-fi
-
-status=0
-curl --silent --fail --head --output /dev/null \
- --max-time "$CI_TIMEOUT" \
- ${CI_NETRC:+--netrc-file "$CI_NETRC"} \
- "$probe" >/dev/null 2>&1 || status=1
-
-if test -d "$CI_CACHE_DIR"
-then
- printf '%s\n' "$status" >"$cache.$$" 2>/dev/null &&
- mv "$cache.$$" "$cache" 2>/dev/null
-fi
-
-exit "$status"
diff --git a/filters/commit-links.sh b/filters/commit-links.sh
index 796ac30..5881952 100755
--- a/filters/commit-links.sh
+++ b/filters/commit-links.sh
@@ -19,7 +19,7 @@ regex=''
# This expression generates links to commits referenced by their SHA1.
regex=$regex'
-s|\b([0-9a-fA-F]{7,64})\b|<a href="./?id=\1">\1</a>|g'
+s|\b([0-9a-fA-F]{7,40})\b|<a href="./?id=\1">\1</a>|g'
# This expression generates links to a fictional bugtracker.
regex=$regex'
diff --git a/filters/email-gravatar.lua b/filters/email-gravatar.lua
index c39b490..52cf426 100644
--- a/filters/email-gravatar.lua
+++ b/filters/email-gravatar.lua
@@ -3,24 +3,15 @@
-- prefix in filters. It is much faster than the corresponding python script.
--
-- Requirements:
--- luaossl
--- <http://25thandclement.com/~william/projects/luaossl.html>
+-- luacrypto >= 0.3
+-- <http://mkottman.github.io/luacrypto/>
--
-local digest = require("openssl.digest")
-
-function md5_hex(input)
- local b = digest.new("md5"):final(input)
- local x = ""
- for i = 1, #b do
- x = x .. string.format("%.2x", string.byte(b, i))
- end
- return x
-end
+local crypto = require("crypto")
function filter_open(email, page)
buffer = ""
- md5 = md5_hex(email:sub(2, -2):lower())
+ md5 = crypto.digest("md5", email:sub(2, -2):lower())
end
function filter_close()
diff --git a/filters/email-libravatar.lua b/filters/email-libravatar.lua
index 7336baf..b0e2447 100644
--- a/filters/email-libravatar.lua
+++ b/filters/email-libravatar.lua
@@ -3,24 +3,15 @@
-- prefix in filters.
--
-- Requirements:
--- luaossl
--- <http://25thandclement.com/~william/projects/luaossl.html>
+-- luacrypto >= 0.3
+-- <http://mkottman.github.io/luacrypto/>
--
-local digest = require("openssl.digest")
-
-function md5_hex(input)
- local b = digest.new("md5"):final(input)
- local x = ""
- for i = 1, #b do
- x = x .. string.format("%.2x", string.byte(b, i))
- end
- return x
-end
+local crypto = require("crypto")
function filter_open(email, page)
buffer = ""
- md5 = md5_hex(email:sub(2, -2):lower())
+ md5 = crypto.digest("md5", email:sub(2, -2):lower())
end
function filter_close()
diff --git a/filters/file-authentication.lua b/filters/file-authentication.lua
deleted file mode 100644
index 0248804..0000000
--- a/filters/file-authentication.lua
+++ /dev/null
@@ -1,359 +0,0 @@
--- This script may be used with the auth-filter.
---
--- Requirements:
--- luaossl
--- <http://25thandclement.com/~william/projects/luaossl.html>
--- luaposix
--- <https://github.com/luaposix/luaposix>
---
-local sysstat = require("posix.sys.stat")
-local unistd = require("posix.unistd")
-local rand = require("openssl.rand")
-local hmac = require("openssl.hmac")
-
--- This file should contain a series of lines in the form of:
--- username1:hash1
--- username2:hash2
--- username3:hash3
--- ...
--- Hashes can be generated using something like `mkpasswd -m sha-512 -R 300000`.
--- This file should not be world-readable.
-local users_filename = "/etc/cgit-auth/users"
-
--- This file should contain a series of lines in the form of:
--- groupname1:username1,username2,username3,...
--- ...
-local groups_filename = "/etc/cgit-auth/groups"
-
--- This file should contain a series of lines in the form of:
--- reponame1:groupname1,groupname2,groupname3,...
--- ...
-local repos_filename = "/etc/cgit-auth/repos"
-
--- Set this to a path this script can write to for storing a persistent
--- cookie secret, which should not be world-readable.
-local secret_filename = "/var/cache/cgit/auth-secret"
-
---
---
--- Authentication functions follow below. Swap these out if you want different authentication semantics.
---
---
-
--- Looks up a hash for a given user.
-function lookup_hash(user)
- local line
- for line in io.lines(users_filename) do
- local u, h = string.match(line, "(.-):(.+)")
- if u:lower() == user:lower() then
- return h
- end
- end
- return nil
-end
-
--- Looks up users for a given repo.
-function lookup_users(repo)
- local users = nil
- local groups = nil
- local line, group, user
- for line in io.lines(repos_filename) do
- local r, g = string.match(line, "(.-):(.+)")
- if r == repo then
- groups = { }
- for group in string.gmatch(g, "([^,]+)") do
- groups[group:lower()] = true
- end
- break
- end
- end
- if groups == nil then
- return nil
- end
- for line in io.lines(groups_filename) do
- local g, u = string.match(line, "(.-):(.+)")
- if groups[g:lower()] then
- if users == nil then
- users = { }
- end
- for user in string.gmatch(u, "([^,]+)") do
- users[user:lower()] = true
- end
- end
- end
- return users
-end
-
-
--- Sets HTTP cookie headers based on post and sets up redirection.
-function authenticate_post()
- local hash = lookup_hash(post["username"])
- local redirect = validate_value("redirect", post["redirect"])
-
- if redirect == nil then
- not_found()
- return 0
- end
-
- redirect_to(redirect)
-
- if hash == nil or hash ~= unistd.crypt(post["password"], hash) then
- set_cookie("cgitauth", "")
- else
- -- One week expiration time
- local username = secure_value("username", post["username"], os.time() + 604800)
- set_cookie("cgitauth", username)
- end
-
- html("\n")
- return 0
-end
-
-
--- Returns 1 if the cookie is valid and 0 if it is not.
-function authenticate_cookie()
- accepted_users = lookup_users(cgit["repo"])
- if accepted_users == nil then
- -- We return as valid if the repo is not protected.
- return 1
- end
-
- local username = validate_value("username", get_cookie(http["cookie"], "cgitauth"))
- if username == nil or not accepted_users[username:lower()] then
- return 0
- else
- return 1
- end
-end
-
--- Prints the html for the login form.
-function body()
- html("<h2>Authentication Required</h2>")
- html("<form method='post' action='")
- html_attr(cgit["login"])
- html("'>")
- html("<input type='hidden' name='redirect' value='")
- html_attr(secure_value("redirect", cgit["url"], 0))
- html("' />")
- html("<table>")
- html("<tr><td><label for='username'>Username:</label></td><td><input id='username' name='username' autofocus /></td></tr>")
- html("<tr><td><label for='password'>Password:</label></td><td><input id='password' name='password' type='password' /></td></tr>")
- html("<tr><td colspan='2'><input value='Login' type='submit' /></td></tr>")
- html("</table></form>")
-
- return 0
-end
-
-
-
---
---
--- Wrapper around filter API, exposing the http table, the cgit table, and the post table to the above functions.
---
---
-
-local actions = {}
-actions["authenticate-post"] = authenticate_post
-actions["authenticate-cookie"] = authenticate_cookie
-actions["body"] = body
-
-function filter_open(...)
- action = actions[select(1, ...)]
-
- http = {}
- http["cookie"] = select(2, ...)
- http["method"] = select(3, ...)
- http["query"] = select(4, ...)
- http["referer"] = select(5, ...)
- http["path"] = select(6, ...)
- http["host"] = select(7, ...)
- http["https"] = select(8, ...)
-
- cgit = {}
- cgit["repo"] = select(9, ...)
- cgit["page"] = select(10, ...)
- cgit["url"] = select(11, ...)
- cgit["login"] = select(12, ...)
-
-end
-
-function filter_close()
- return action()
-end
-
-function filter_write(str)
- post = parse_qs(str)
-end
-
-
---
---
--- Utility functions based on keplerproject/wsapi.
---
---
-
-function url_decode(str)
- if not str then
- return ""
- end
- str = string.gsub(str, "+", " ")
- str = string.gsub(str, "%%(%x%x)", function(h) return string.char(tonumber(h, 16)) end)
- str = string.gsub(str, "\r\n", "\n")
- return str
-end
-
-function url_encode(str)
- if not str then
- return ""
- end
- str = string.gsub(str, "\n", "\r\n")
- str = string.gsub(str, "([^%w ])", function(c) return string.format("%%%02X", string.byte(c)) end)
- str = string.gsub(str, " ", "+")
- return str
-end
-
-function parse_qs(qs)
- local tab = {}
- for key, val in string.gmatch(qs, "([^&=]+)=([^&=]*)&?") do
- tab[url_decode(key)] = url_decode(val)
- end
- return tab
-end
-
-function get_cookie(cookies, name)
- cookies = string.gsub(";" .. cookies .. ";", "%s*;%s*", ";")
- return url_decode(string.match(cookies, ";" .. name .. "=(.-);"))
-end
-
-function tohex(b)
- local x = ""
- for i = 1, #b do
- x = x .. string.format("%.2x", string.byte(b, i))
- end
- return x
-end
-
---
---
--- Cookie construction and validation helpers.
---
---
-
-local secret = nil
-
--- Loads a secret from a file, creates a secret, or returns one from memory.
-function get_secret()
- if secret ~= nil then
- return secret
- end
- local secret_file = io.open(secret_filename, "r")
- if secret_file == nil then
- local old_umask = sysstat.umask(63)
- local temporary_filename = secret_filename .. ".tmp." .. tohex(rand.bytes(16))
- local temporary_file = io.open(temporary_filename, "w")
- if temporary_file == nil then
- os.exit(177)
- end
- temporary_file:write(tohex(rand.bytes(32)))
- temporary_file:close()
- unistd.link(temporary_filename, secret_filename) -- Intentionally fails in the case that another process is doing the same.
- unistd.unlink(temporary_filename)
- sysstat.umask(old_umask)
- secret_file = io.open(secret_filename, "r")
- end
- if secret_file == nil then
- os.exit(177)
- end
- secret = secret_file:read()
- secret_file:close()
- if secret:len() ~= 64 then
- os.exit(177)
- end
- return secret
-end
-
--- Returns value of cookie if cookie is valid. Otherwise returns nil.
-function validate_value(expected_field, cookie)
- local i = 0
- local value = ""
- local field = ""
- local expiration = 0
- local salt = ""
- local chmac = ""
-
- if cookie == nil or cookie:len() < 3 or cookie:sub(1, 1) == "|" then
- return nil
- end
-
- for component in string.gmatch(cookie, "[^|]+") do
- if i == 0 then
- field = component
- elseif i == 1 then
- value = component
- elseif i == 2 then
- expiration = tonumber(component)
- if expiration == nil then
- expiration = -1
- end
- elseif i == 3 then
- salt = component
- elseif i == 4 then
- chmac = component
- else
- break
- end
- i = i + 1
- end
-
- if chmac == nil or chmac:len() == 0 then
- return nil
- end
-
- -- Lua hashes strings, so these comparisons are time invariant.
- if chmac ~= tohex(hmac.new(get_secret(), "sha256"):final(field .. "|" .. value .. "|" .. tostring(expiration) .. "|" .. salt)) then
- return nil
- end
-
- if expiration == -1 or (expiration ~= 0 and expiration <= os.time()) then
- return nil
- end
-
- if url_decode(field) ~= expected_field then
- return nil
- end
-
- return url_decode(value)
-end
-
-function secure_value(field, value, expiration)
- if value == nil or value:len() <= 0 then
- return ""
- end
-
- local authstr = ""
- local salt = tohex(rand.bytes(16))
- value = url_encode(value)
- field = url_encode(field)
- authstr = field .. "|" .. value .. "|" .. tostring(expiration) .. "|" .. salt
- authstr = authstr .. "|" .. tohex(hmac.new(get_secret(), "sha256"):final(authstr))
- return authstr
-end
-
-function set_cookie(cookie, value)
- html("Set-Cookie: " .. cookie .. "=" .. value .. "; HttpOnly")
- if http["https"] == "yes" or http["https"] == "on" or http["https"] == "1" then
- html("; secure")
- end
- html("\n")
-end
-
-function redirect_to(url)
- html("Status: 302 Redirect\n")
- html("Cache-Control: no-cache, no-store\n")
- html("Location: " .. url .. "\n")
-end
-
-function not_found()
- html("Status: 404 Not Found\n")
- html("Cache-Control: no-cache, no-store\n\n")
-end
diff --git a/filters/gentoo-ldap-authentication.lua b/filters/gentoo-ldap-authentication.lua
index 673c88d..6d8eb3e 100644
--- a/filters/gentoo-ldap-authentication.lua
+++ b/filters/gentoo-ldap-authentication.lua
@@ -1,18 +1,12 @@
-- This script may be used with the auth-filter. Be sure to configure it as you wish.
--
-- Requirements:
--- luaossl
--- <http://25thandclement.com/~william/projects/luaossl.html>
+-- luacrypto >= 0.3
+-- <http://mkottman.github.io/luacrypto/>
-- lualdap >= 1.2
-- <https://git.zx2c4.com/lualdap/about/>
--- luaposix
--- <https://github.com/luaposix/luaposix>
--
-local sysstat = require("posix.sys.stat")
-local unistd = require("posix.unistd")
-local lualdap = require("lualdap")
-local rand = require("openssl.rand")
-local hmac = require("openssl.hmac")
+
--
--
@@ -27,9 +21,11 @@ local protected_repos = {
portage = "dev"
}
--- Set this to a path this script can write to for storing a persistent
--- cookie secret, which should be guarded.
-local secret_filename = "/var/cache/cgit/auth-secret"
+
+-- All cookies will be authenticated based on this secret. Make it something
+-- totally random and impossible to guess. It should be large.
+local secret = "BE SURE TO CUSTOMIZE THIS STRING TO SOMETHING BIG AND RANDOM"
+
--
@@ -106,9 +102,11 @@ end
--
--
+local lualdap = require("lualdap")
+
function gentoo_ldap_user_groups(username, password)
-- Ensure the user is alphanumeric
- if username == nil or username:match("%W") then
+ if username:match("%W") then
return nil
end
@@ -226,13 +224,6 @@ function get_cookie(cookies, name)
return string.match(cookies, ";" .. name .. "=(.-);")
end
-function tohex(b)
- local x = ""
- for i = 1, #b do
- x = x .. string.format("%.2x", string.byte(b, i))
- end
- return x
-end
--
--
@@ -240,38 +231,7 @@ end
--
--
-local secret = nil
-
--- Loads a secret from a file, creates a secret, or returns one from memory.
-function get_secret()
- if secret ~= nil then
- return secret
- end
- local secret_file = io.open(secret_filename, "r")
- if secret_file == nil then
- local old_umask = sysstat.umask(63)
- local temporary_filename = secret_filename .. ".tmp." .. tohex(rand.bytes(16))
- local temporary_file = io.open(temporary_filename, "w")
- if temporary_file == nil then
- os.exit(177)
- end
- temporary_file:write(tohex(rand.bytes(32)))
- temporary_file:close()
- unistd.link(temporary_filename, secret_filename) -- Intentionally fails in the case that another process is doing the same.
- unistd.unlink(temporary_filename)
- sysstat.umask(old_umask)
- secret_file = io.open(secret_filename, "r")
- end
- if secret_file == nil then
- os.exit(177)
- end
- secret = secret_file:read()
- secret_file:close()
- if secret:len() ~= 64 then
- os.exit(177)
- end
- return secret
-end
+local crypto = require("crypto")
-- Returns value of cookie if cookie is valid. Otherwise returns nil.
function validate_value(expected_field, cookie)
@@ -280,7 +240,7 @@ function validate_value(expected_field, cookie)
local field = ""
local expiration = 0
local salt = ""
- local chmac = ""
+ local hmac = ""
if cookie == nil or cookie:len() < 3 or cookie:sub(1, 1) == "|" then
return nil
@@ -299,19 +259,19 @@ function validate_value(expected_field, cookie)
elseif i == 3 then
salt = component
elseif i == 4 then
- chmac = component
+ hmac = component
else
break
end
i = i + 1
end
- if chmac == nil or chmac:len() == 0 then
+ if hmac == nil or hmac:len() == 0 then
return nil
end
-- Lua hashes strings, so these comparisons are time invariant.
- if chmac ~= tohex(hmac.new(get_secret(), "sha256"):final(field .. "|" .. value .. "|" .. tostring(expiration) .. "|" .. salt)) then
+ if hmac ~= crypto.hmac.digest("sha1", field .. "|" .. value .. "|" .. tostring(expiration) .. "|" .. salt, secret) then
return nil
end
@@ -332,11 +292,11 @@ function secure_value(field, value, expiration)
end
local authstr = ""
- local salt = tohex(rand.bytes(16))
+ local salt = crypto.hex(crypto.rand.bytes(16))
value = url_encode(value)
field = url_encode(field)
authstr = field .. "|" .. value .. "|" .. tostring(expiration) .. "|" .. salt
- authstr = authstr .. "|" .. tohex(hmac.new(get_secret(), "sha256"):final(authstr))
+ authstr = authstr .. "|" .. crypto.hmac.digest("sha1", authstr, secret)
return authstr
end
diff --git a/filters/html-converters/md2html b/filters/html-converters/md2html
index 4f6ad37..ebf3856 100755
--- a/filters/html-converters/md2html
+++ b/filters/html-converters/md2html
@@ -2,46 +2,7 @@
import markdown
import sys
import io
-from markdown.extensions.toc import TocExtension
-
-# Pygments' token classes, mapped onto the --syn-* custom properties that
-# cgit.css defines. The fallbacks are the palette those properties default to,
-# so that the output stays readable under a stylesheet without them.
-SYNTAX_COLORS = (
- (('k', 'kc', 'kd', 'kn', 'kr'), '--syn-keyword', '#000',
- 'font-weight: bold'),
- (('kp',), '--syn-keyword', '#000', None),
- (('kt',), '--syn-type', '#010181', None),
- (('nc', 'nf', 'nn', 'ne'), '--syn-keyword-alt', '#0057ae', None),
- (('s', 'sa', 'sb', 'sc', 'dl', 'sd', 's2', 'sh', 'sx', 'sr', 's1', 'ss'),
- '--syn-string', '#bf0303', None),
- (('se',), '--syn-escape', '#f0f', None),
- (('si',), '--syn-interpolation', '#0057ae', None),
- (('c', 'ch', 'cm', 'c1', 'cs'), '--syn-comment', '#838183',
- 'font-style: italic'),
- (('cp', 'cpf'), '--syn-preproc', '#008200', None),
- (('m', 'mb', 'mf', 'mh', 'mi', 'mo', 'il'), '--syn-number', '#b07e00',
- None),
- (('o', 'ow', 'p'), '--syn-operator', '#000', None),
- (('err',), '--syn-error', '#bf0303', None),
- (('gd',), '--red', 'red', None),
- (('gi',), '--green', 'green', None),
- (('lineno', 'linenos'), '--syn-linenum', '#555', None),
-)
-
-
-def style_defs(prefix='.highlight'):
- rules = []
- for classes, prop, fallback, extra in SYNTAX_COLORS:
- selector = ', '.join('%s .%s' % (prefix, c) for c in classes)
- decls = 'color: var(%s, %s)' % (prop, fallback)
- if extra:
- decls += '; ' + extra
- rules.append('%s { %s }' % (selector, decls))
- rules.append('%s .hll { background-color: var(--syn-mark-bg, #ffb) }'
- % prefix)
- return '\n'.join(rules) + '\n'
-
+from pygments.formatters import HtmlFormatter
sys.stdin = io.TextIOWrapper(sys.stdin.buffer, encoding='utf-8')
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
sys.stdout.write('''
@@ -58,7 +19,7 @@ sys.stdout.write('''
margin-bottom: 0 !important;
}
.markdown-body a.absent {
- color: var(--red-mid, #c00);
+ color: #c00;
}
.markdown-body a.anchor {
display: block;
@@ -80,32 +41,28 @@ sys.stdout.write('''
}
.markdown-body h1 .mini-icon-link, .markdown-body h2 .mini-icon-link, .markdown-body h3 .mini-icon-link, .markdown-body h4 .mini-icon-link, .markdown-body h5 .mini-icon-link, .markdown-body h6 .mini-icon-link {
display: none;
- color: var(--fg-strong, #000);
+ color: #000;
}
.markdown-body h1:hover a.anchor, .markdown-body h2:hover a.anchor, .markdown-body h3:hover a.anchor, .markdown-body h4:hover a.anchor, .markdown-body h5:hover a.anchor, .markdown-body h6:hover a.anchor {
text-decoration: none;
line-height: 1;
padding-left: 0;
margin-left: -22px;
- top: 15%;
-}
+ top: 15%}
.markdown-body h1:hover a.anchor .mini-icon-link, .markdown-body h2:hover a.anchor .mini-icon-link, .markdown-body h3:hover a.anchor .mini-icon-link, .markdown-body h4:hover a.anchor .mini-icon-link, .markdown-body h5:hover a.anchor .mini-icon-link, .markdown-body h6:hover a.anchor .mini-icon-link {
display: inline-block;
}
-div#cgit .markdown-body h1 a.toclink, div#cgit .markdown-body h2 a.toclink, div#cgit .markdown-body h3 a.toclink, div#cgit .markdown-body h4 a.toclink, div#cgit .markdown-body h5 a.toclink, div#cgit .markdown-body h6 a.toclink {
- color: var(--fg-strong, #000);
-}
.markdown-body h1 tt, .markdown-body h1 code, .markdown-body h2 tt, .markdown-body h2 code, .markdown-body h3 tt, .markdown-body h3 code, .markdown-body h4 tt, .markdown-body h4 code, .markdown-body h5 tt, .markdown-body h5 code, .markdown-body h6 tt, .markdown-body h6 code {
font-size: inherit;
}
.markdown-body h1 {
font-size: 28px;
- color: var(--fg-strong, #000);
+ color: #000;
}
.markdown-body h2 {
font-size: 24px;
- border-bottom: 1px solid var(--border, #ccc);
- color: var(--fg-strong, #000);
+ border-bottom: 1px solid #ccc;
+ color: #000;
}
.markdown-body h3 {
font-size: 18px;
@@ -117,14 +74,18 @@ div#cgit .markdown-body h1 a.toclink, div#cgit .markdown-body h2 a.toclink, div#
font-size: 14px;
}
.markdown-body h6 {
- color: var(--fg-mute, #777);
+ color: #777;
font-size: 14px;
}
.markdown-body p, .markdown-body blockquote, .markdown-body ul, .markdown-body ol, .markdown-body dl, .markdown-body table, .markdown-body pre {
margin: 15px 0;
}
.markdown-body hr {
- border: 2px solid var(--border, #ccc);
+ background: transparent url("/dirty-shade.png") repeat-x 0 0;
+ border: 0 none;
+ color: #ccc;
+ height: 4px;
+ padding: 0;
}
.markdown-body>h2:first-child, .markdown-body>h1:first-child, .markdown-body>h1:first-child+h2, .markdown-body>h3:first-child, .markdown-body>h4:first-child, .markdown-body>h5:first-child, .markdown-body>h6:first-child {
margin-top: 0;
@@ -186,9 +147,9 @@ div#cgit .markdown-body h1 a.toclink, div#cgit .markdown-body h2 a.toclink, div#
margin-bottom: 0px;
}
.markdown-body blockquote {
- border-left: 4px solid var(--border, #ddd);
+ border-left: 4px solid #DDD;
padding: 0 15px;
- color: var(--fg-mute, #777);
+ color: #777;
}
.markdown-body blockquote>:first-child {
margin-top: 0px;
@@ -200,15 +161,15 @@ div#cgit .markdown-body h1 a.toclink, div#cgit .markdown-body h2 a.toclink, div#
font-weight: bold;
}
.markdown-body table th, .markdown-body table td {
- border: 1px solid var(--border, #ccc);
+ border: 1px solid #ccc;
padding: 6px 13px;
}
.markdown-body table tr {
- border-top: 1px solid var(--border, #ccc);
- background-color: var(--bg, #fff);
+ border-top: 1px solid #ccc;
+ background-color: #fff;
}
.markdown-body table tr:nth-child(2n) {
- background-color: var(--bg-zebra, #f8f8f8);
+ background-color: #f8f8f8;
}
.markdown-body img {
max-width: 100%;
@@ -220,7 +181,7 @@ div#cgit .markdown-body h1 a.toclink, div#cgit .markdown-body h2 a.toclink, div#
overflow: hidden;
}
.markdown-body span.frame>span {
- border: 1px solid var(--border, #ddd);
+ border: 1px solid #ddd;
display: block;
float: left;
overflow: hidden;
@@ -234,7 +195,7 @@ div#cgit .markdown-body h1 a.toclink, div#cgit .markdown-body h2 a.toclink, div#
}
.markdown-body span.frame span span {
clear: both;
- color: var(--fg, #333);
+ color: #333;
display: block;
padding: 5px 0 0;
}
@@ -292,8 +253,8 @@ div#cgit .markdown-body h1 a.toclink, div#cgit .markdown-body h2 a.toclink, div#
.markdown-body code, .markdown-body tt {
margin: 0 2px;
padding: 0px 5px;
- border: 1px solid var(--border, #eaeaea);
- background-color: var(--bg-zebra, #f8f8f8);
+ border: 1px solid #eaeaea;
+ background-color: #f8f8f8;
border-radius: 3px;
}
.markdown-body code {
@@ -307,8 +268,8 @@ div#cgit .markdown-body h1 a.toclink, div#cgit .markdown-body h2 a.toclink, div#
background: transparent;
}
.markdown-body .highlight pre, .markdown-body pre {
- background-color: var(--bg-zebra, #f8f8f8);
- border: 1px solid var(--border, #ccc);
+ background-color: #f8f8f8;
+ border: 1px solid #ccc;
font-size: 13px;
line-height: 19px;
overflow: auto;
@@ -322,21 +283,12 @@ div#cgit .markdown-body h1 a.toclink, div#cgit .markdown-body h2 a.toclink, div#
border: none;
}
''')
-sys.stdout.write(style_defs('.highlight'))
+sys.stdout.write(HtmlFormatter(style='pastie').get_style_defs('.highlight'))
sys.stdout.write('''
-</style>
+</style>
''')
sys.stdout.write("<div class='markdown-body'>")
sys.stdout.flush()
# Note: you may want to run this through bleach for sanitization
-markdown.markdownFromFile(
- output_format="html5",
- extensions=[
- "markdown.extensions.fenced_code",
- "markdown.extensions.codehilite",
- "markdown.extensions.tables",
- "markdown.extensions.sane_lists",
- TocExtension(anchorlink=True)],
- extension_configs={
- "markdown.extensions.codehilite":{"css_class":"highlight"}})
+markdown.markdownFromFile(output_format="html5", extensions=["markdown.extensions.fenced_code", "markdown.extensions.codehilite", "markdown.extensions.tables"], extension_configs={"markdown.extensions.codehilite":{"css_class":"highlight"}})
sys.stdout.write("</div>")
diff --git a/filters/simple-authentication.lua b/filters/simple-authentication.lua
index 23d3457..de34d09 100644
--- a/filters/simple-authentication.lua
+++ b/filters/simple-authentication.lua
@@ -1,15 +1,10 @@
-- This script may be used with the auth-filter. Be sure to configure it as you wish.
--
-- Requirements:
--- luaossl
--- <http://25thandclement.com/~william/projects/luaossl.html>
--- luaposix
--- <https://github.com/luaposix/luaposix>
+-- luacrypto >= 0.3
+-- <http://mkottman.github.io/luacrypto/>
--
-local sysstat = require("posix.sys.stat")
-local unistd = require("posix.unistd")
-local rand = require("openssl.rand")
-local hmac = require("openssl.hmac")
+
--
--
@@ -23,16 +18,24 @@ local protected_repos = {
qt = { jason = true, bob = true }
}
--- A list of users and hashes, generated with `mkpasswd -m sha-512 -R 300000`.
+-- Please note that, in production, you'll want to replace this simple lookup
+-- table with either a table of salted and hashed passwords (using something
+-- smart like scrypt), or replace this table lookup with an external support,
+-- such as consulting your system's pam / shadow system, or an external
+-- database, or an external validating web service. For testing, or for
+-- extremely low-security usage, you may be able, however, to get away with
+-- compromising on hardcoding the passwords in cleartext, as we have done here.
local users = {
- jason = "$6$rounds=300000$YYJct3n/o.ruYK$HhpSeuCuW1fJkpvMZOZzVizeLsBKcGA/aF2UPuV5v60JyH2MVSG6P511UMTj2F3H75.IT2HIlnvXzNb60FcZH1",
- laurent = "$6$rounds=300000$dP0KNHwYb3JKigT$pN/LG7rWxQ4HniFtx5wKyJXBJUKP7R01zTNZ0qSK/aivw8ywGAOdfYiIQFqFhZFtVGvr11/7an.nesvm8iJUi.",
- bob = "$6$rounds=300000$jCLCCt6LUpTz$PI1vvd1yaVYcCzqH8QAJFcJ60b6W/6sjcOsU7mAkNo7IE8FRGW1vkjF8I/T5jt/auv5ODLb1L4S2s.CAyZyUC"
+ jason = "secretpassword",
+ laurent = "s3cr3t",
+ bob = "ilikelua"
}
--- Set this to a path this script can write to for storing a persistent
--- cookie secret, which should be guarded.
-local secret_filename = "/var/cache/cgit/auth-secret"
+-- All cookies will be authenticated based on this secret. Make it something
+-- totally random and impossible to guess. It should be large.
+local secret = "BE SURE TO CUSTOMIZE THIS STRING TO SOMETHING BIG AND RANDOM"
+
+
--
--
@@ -42,7 +45,7 @@ local secret_filename = "/var/cache/cgit/auth-secret"
-- Sets HTTP cookie headers based on post and sets up redirection.
function authenticate_post()
- local hash = users[post["username"]]
+ local password = users[post["username"]]
local redirect = validate_value("redirect", post["redirect"])
if redirect == nil then
@@ -52,7 +55,8 @@ function authenticate_post()
redirect_to(redirect)
- if hash == nil or hash ~= unistd.crypt(post["password"], hash) then
+ -- Lua hashes strings, so these comparisons are time invariant.
+ if password == nil or password ~= post["password"] then
set_cookie("cgitauth", "")
else
-- One week expiration time
@@ -180,13 +184,6 @@ function get_cookie(cookies, name)
return url_decode(string.match(cookies, ";" .. name .. "=(.-);"))
end
-function tohex(b)
- local x = ""
- for i = 1, #b do
- x = x .. string.format("%.2x", string.byte(b, i))
- end
- return x
-end
--
--
@@ -194,38 +191,7 @@ end
--
--
-local secret = nil
-
--- Loads a secret from a file, creates a secret, or returns one from memory.
-function get_secret()
- if secret ~= nil then
- return secret
- end
- local secret_file = io.open(secret_filename, "r")
- if secret_file == nil then
- local old_umask = sysstat.umask(63)
- local temporary_filename = secret_filename .. ".tmp." .. tohex(rand.bytes(16))
- local temporary_file = io.open(temporary_filename, "w")
- if temporary_file == nil then
- os.exit(177)
- end
- temporary_file:write(tohex(rand.bytes(32)))
- temporary_file:close()
- unistd.link(temporary_filename, secret_filename) -- Intentionally fails in the case that another process is doing the same.
- unistd.unlink(temporary_filename)
- sysstat.umask(old_umask)
- secret_file = io.open(secret_filename, "r")
- end
- if secret_file == nil then
- os.exit(177)
- end
- secret = secret_file:read()
- secret_file:close()
- if secret:len() ~= 64 then
- os.exit(177)
- end
- return secret
-end
+local crypto = require("crypto")
-- Returns value of cookie if cookie is valid. Otherwise returns nil.
function validate_value(expected_field, cookie)
@@ -234,7 +200,7 @@ function validate_value(expected_field, cookie)
local field = ""
local expiration = 0
local salt = ""
- local chmac = ""
+ local hmac = ""
if cookie == nil or cookie:len() < 3 or cookie:sub(1, 1) == "|" then
return nil
@@ -253,19 +219,19 @@ function validate_value(expected_field, cookie)
elseif i == 3 then
salt = component
elseif i == 4 then
- chmac = component
+ hmac = component
else
break
end
i = i + 1
end
- if chmac == nil or chmac:len() == 0 then
+ if hmac == nil or hmac:len() == 0 then
return nil
end
-- Lua hashes strings, so these comparisons are time invariant.
- if chmac ~= tohex(hmac.new(get_secret(), "sha256"):final(field .. "|" .. value .. "|" .. tostring(expiration) .. "|" .. salt)) then
+ if hmac ~= crypto.hmac.digest("sha1", field .. "|" .. value .. "|" .. tostring(expiration) .. "|" .. salt, secret) then
return nil
end
@@ -286,11 +252,11 @@ function secure_value(field, value, expiration)
end
local authstr = ""
- local salt = tohex(rand.bytes(16))
+ local salt = crypto.hex(crypto.rand.bytes(16))
value = url_encode(value)
field = url_encode(field)
authstr = field .. "|" .. value .. "|" .. tostring(expiration) .. "|" .. salt
- authstr = authstr .. "|" .. tohex(hmac.new(get_secret(), "sha256"):final(authstr))
+ authstr = authstr .. "|" .. crypto.hmac.digest("sha1", authstr, secret)
return authstr
end
diff --git a/filters/syntax-highlighting.py b/filters/syntax-highlighting.py
index d757e2d..e912594 100755
--- a/filters/syntax-highlighting.py
+++ b/filters/syntax-highlighting.py
@@ -30,50 +30,11 @@ from pygments.lexers import guess_lexer_for_filename
from pygments.formatters import HtmlFormatter
-# Pygments' token classes, mapped onto the --syn-* custom properties that
-# cgit.css defines. The fallbacks are the palette those properties default to,
-# so that the output stays readable under a stylesheet without them.
-SYNTAX_COLORS = (
- (('k', 'kc', 'kd', 'kn', 'kr'), '--syn-keyword', '#000',
- 'font-weight: bold'),
- (('kp',), '--syn-keyword', '#000', None),
- (('kt',), '--syn-type', '#010181', None),
- (('nc', 'nf', 'nn', 'ne'), '--syn-keyword-alt', '#0057ae', None),
- (('s', 'sa', 'sb', 'sc', 'dl', 'sd', 's2', 'sh', 'sx', 'sr', 's1', 'ss'),
- '--syn-string', '#bf0303', None),
- (('se',), '--syn-escape', '#f0f', None),
- (('si',), '--syn-interpolation', '#0057ae', None),
- (('c', 'ch', 'cm', 'c1', 'cs'), '--syn-comment', '#838183',
- 'font-style: italic'),
- (('cp', 'cpf'), '--syn-preproc', '#008200', None),
- (('m', 'mb', 'mf', 'mh', 'mi', 'mo', 'il'), '--syn-number', '#b07e00',
- None),
- (('o', 'ow', 'p'), '--syn-operator', '#000', None),
- (('err',), '--syn-error', '#bf0303', None),
- (('gd',), '--red', 'red', None),
- (('gi',), '--green', 'green', None),
- (('lineno', 'linenos'), '--syn-linenum', '#555', None),
-)
-
-
-def style_defs(prefix='.highlight'):
- rules = []
- for classes, prop, fallback, extra in SYNTAX_COLORS:
- selector = ', '.join('%s .%s' % (prefix, c) for c in classes)
- decls = 'color: var(%s, %s)' % (prop, fallback)
- if extra:
- decls += '; ' + extra
- rules.append('%s { %s }' % (selector, decls))
- rules.append('%s .hll { background-color: var(--syn-mark-bg, #ffb) }'
- % prefix)
- return '\n'.join(rules) + '\n'
-
-
sys.stdin = io.TextIOWrapper(sys.stdin.buffer, encoding='utf-8', errors='replace')
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace')
data = sys.stdin.read()
filename = sys.argv[1]
-formatter = HtmlFormatter(nobackground=True)
+formatter = HtmlFormatter(style='pastie', nobackground=True)
try:
lexer = guess_lexer_for_filename(filename, data)
@@ -87,8 +48,8 @@ except TypeError:
lexer = TextLexer()
# highlight! :-)
-# printout the css definitions for pygments' token classes as well
+# printout pygments' css definitions as well
sys.stdout.write('<style>')
-sys.stdout.write(style_defs('.highlight'))
+sys.stdout.write(formatter.get_style_defs('.highlight'))
sys.stdout.write('</style>')
sys.stdout.write(highlight(data, lexer, formatter, outfile=None))
diff --git a/filters/syntax-highlighting.sh b/filters/syntax-highlighting.sh
index bb8d60c..840bc34 100755
--- a/filters/syntax-highlighting.sh
+++ b/filters/syntax-highlighting.sh
@@ -8,10 +8,8 @@
# might have to use an external call to sed instead.
#
# Note: the highlight command (http://www.andre-simon.de/) uses css for syntax
-# highlighting. cgit.css defines these classes in terms of its --syn-* custom
-# properties, so nothing has to be added when using the default stylesheet.
-# The palette below, from highlight 3.13, is what those properties default to;
-# a custom stylesheet wanting the same colors can use it directly:
+# highlighting, so you'll probably want something like the following included
+# in your css file:
#
# Style definition file generated by highlight 2.4.8, http://www.andre-simon.de/
#
@@ -116,12 +114,8 @@ EXTENSION="${BASENAME##*.}"
# Version 2 can be found (for example) on EPEL 5, while version 3 can be
# found (for example) on EPEL 6.
#
-# Note that -I (--include-style) is not used: the stylesheet it embeds in the
-# output would override the .hl rules in cgit.css and with them any theming
-# done through the --syn-* custom properties.
-#
# This is for version 2
-exec highlight --force -f -X -S "$EXTENSION" 2>/dev/null
+exec highlight --force -f -I -X -S "$EXTENSION" 2>/dev/null
# This is for version 3
-#exec highlight --force -f -O xhtml -S "$EXTENSION" 2>/dev/null
+#exec highlight --force -f -I -O xhtml -S "$EXTENSION" 2>/dev/null