Goit

Simple and lightweight Git web server
git clone https://git.omkov.net/Goit
git clone [email protected]:Goit
Log | Tree | Refs | README | Download

AuthorJakob Wakeling <[email protected]>
Date2025-02-09 00:49:12
Commitdad559f9cef9414fb39d086377ac2cbe989a8bf2
Parent113a52e48aefe1a15a501cea4de5dc6fa32f5024
Branch master

Allow SSH host key persistence

Diffstat

M .gitignore | 4 ----
M Containerfile | 18 +++++++++++++-----
M README.md | 3 +++
M src/admin/cron.go | 6 +++---
M src/goit/ssh.go | 6 +++---
M src/main.go | 2 +-
M src/repo/blame.go | 22 +++++++++++-----------
M src/repo/commit.go | 18 +++++++++---------
M src/repo/create.go | 6 +++---
M src/repo/file.go | 20 ++++++++++----------
M src/repo/log.go | 18 +++++++++---------
M src/repo/refs.go | 14 +++++++-------
M src/repo/tag.go | 16 ++++++++--------
M src/user/keys.go | 18 +++++++++---------
M src/util/log.go | 2 +-

15 files changed, 90 insertions, 83 deletions

diff --git a/.gitignore b/.gitignore
index f43f734..ae3c172 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1 @@
-/.vscode/*
 /bin/
-
-!/.vscode/launch.json
-!/.vscode/tasks.json
diff --git a/Containerfile b/Containerfile
index 82d90f9..f6ecaaf 100644
--- a/Containerfile
+++ b/Containerfile
@@ -13,20 +13,28 @@ RUN apk upgrade
 RUN apk add --no-cache git openssh
 COPY --from=build /app/bin /app/bin
 RUN ln -s /app/bin/goit-shell /usr/local/bin/goit-shell
-RUN ssh-keygen -A
-RUN sed -i 's/^#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
+
 RUN addgroup -g 973 -S git
 RUN adduser -g git -s /bin/sh -G git -S -u 973 git
 RUN sed -i 's/^git:!:/git:*:/' /etc/shadow
 RUN mkdir -p /home/git/.config /home/git/.local/share /home/git/.local/state
 RUN chown -R git:git /home/git/.config /home/git/.local
+
+RUN sed -i 's/^#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
+RUN echo 'HostKey /etc/ssh/host_keys/etc/ssh/ssh_host_rsa_key' >> /etc/ssh/sshd_config.d/00_host_keys.conf
+RUN echo 'HostKey /etc/ssh/host_keys/etc/ssh/ssh_host_ecdsa_key' >> /etc/ssh/sshd_config.d/00_host_keys.conf
+RUN echo 'HostKey /etc/ssh/host_keys/etc/ssh/ssh_host_ed25519_key' >> /etc/ssh/sshd_config.d/00_host_keys.conf
+
 WORKDIR /app
-EXPOSE 8080
-EXPOSE 22
-VOLUME /etc/goit /var/lib/goit /var/log/goit
+EXPOSE 8080/tcp
+EXPOSE 22/tcp
+# VOLUME /home/git/.config/goit /home/git/.local/share/goit /home/git/.local/state/goit
+VOLUME /etc/ssh/host_keys
 
 RUN cat <<EOF > /app/bin/launch.sh
 #!/bin/sh -e
+mkdir -p /etc/ssh/host_keys/etc/ssh
+ssh-keygen -A -f /etc/ssh/host_keys
 /usr/sbin/sshd -D &
 su git -c "/app/bin/goit \$@"
 EOF
diff --git a/README.md b/README.md
index d1db11e..8dc1f7a 100644
--- a/README.md
+++ b/README.md
@@ -26,6 +26,7 @@ podman run -u 0:0 --userns keep-id:uid=973,gid=973 \
 	-v /GOIT/CONFIG/ON/HOST:/home/git/.config/goit:Z \
 	-v /GOIT/DATA/ON/HOST:/home/git/.local/share/goit:Z \
 	-v /GOIT/STATE/ON/HOST:/home/git/.local/state/goit:Z \
+	-v /GOIT/HOST/KEYS/ON/HOST:/etc/ssh/host_keys:Z \
 	-p 8080:8080 -p 2222:22 --name goit goit:0.2.0
 ```
 
@@ -37,6 +38,8 @@ podman run -u 0:0 --userns keep-id:uid=973,gid=973 \
 - Config is stored at `/home/git/.config/goit` inside the container.
 - Data is stored at `/home/git/.local/share/goit` inside the container.
 - State is stored at `/home/git/.local/state/goit` inside the container.
+- Host keys are stored at `/etc/ssh/host_keys/etc/ssh` inside the container,
+  mounting a host directory at this location will persist SSH keys.
 - The port 8080 is exposed inside the container for HTTP.
 - The port 22 is exposed inside the container for SSH.
 
diff --git a/src/admin/cron.go b/src/admin/cron.go
index 4f46689..94263b3 100644
--- a/src/admin/cron.go
+++ b/src/admin/cron.go
@@ -15,7 +15,7 @@ import (
 func HandleCron(w http.ResponseWriter, r *http.Request) {
 	auth, user, err := goit.Auth(w, r, true)
 	if err != nil {
-		util.PrintFuncError(err)
+		util.PrintError(err)
 		goit.HttpError(w, http.StatusInternalServerError)
 		return
 	}
@@ -36,7 +36,7 @@ func HandleCron(w http.ResponseWriter, r *http.Request) {
 
 		if job.RID != -1 {
 			if r, err := goit.GetRepo(job.RID); err != nil {
-				util.PrintFuncError(err)
+				util.PrintError(err)
 			} else if r != nil {
 				repo = r
 			}
@@ -53,6 +53,6 @@ func HandleCron(w http.ResponseWriter, r *http.Request) {
 	}
 
 	if err := goit.Tmpl.ExecuteTemplate(w, "admin/cron", data); err != nil {
-		util.PrintFuncError(err)
+		util.PrintError(err)
 	}
 }
diff --git a/src/goit/ssh.go b/src/goit/ssh.go
index f4adb1c..c0cf08a 100644
--- a/src/goit/ssh.go
+++ b/src/goit/ssh.go
@@ -41,7 +41,7 @@ func UpdateAuthorizedKeys() error {
 	for _, u := range users {
 		keys, err := GetKeys(u.Id)
 		if err != nil {
-			util.PrintFuncError(err)
+			util.PrintError(err)
 			continue
 		}
 
@@ -52,14 +52,14 @@ func UpdateAuthorizedKeys() error {
 
 			ks, err := ssh.ParsePublicKey(k.Key)
 			if err != nil {
-				util.PrintFuncError(err)
+				util.PrintError(err)
 				continue
 			}
 
 			if _, err := f.WriteString(
 				fmt.Sprintf("command=\"goit-shell %s\" %s", u.Name, string(ssh.MarshalAuthorizedKey(ks))),
 			); err != nil {
-				util.PrintFuncError(err)
+				util.PrintError(err)
 				continue
 			}
 		}
diff --git a/src/main.go b/src/main.go
index 1c728cf..3709d78 100644
--- a/src/main.go
+++ b/src/main.go
@@ -35,7 +35,7 @@ func main() {
 
 	if backup {
 		if err := goit.Backup(); err != nil {
-			util.PrintFuncError(err)
+			util.PrintError(err)
 		}
 
 		os.Exit(0)
diff --git a/src/repo/blame.go b/src/repo/blame.go
index c42d3bb..3314a58 100644
--- a/src/repo/blame.go
+++ b/src/repo/blame.go
@@ -23,7 +23,7 @@ import (
 func HandleBlame(w http.ResponseWriter, r *http.Request) {
 	auth, user, err := goit.Auth(w, r, true)
 	if err != nil {
-		util.PrintFuncError(err)
+		util.PrintError(err)
 		goit.HttpError(w, http.StatusInternalServerError)
 		return
 	}
@@ -56,7 +56,7 @@ func HandleBlame(w http.ResponseWriter, r *http.Request) {
 
 	gr, err := git.PlainOpen(goit.RepoPath(repo.Name, true))
 	if err != nil {
-		util.PrintFuncError(err)
+		util.PrintError(err)
 		goit.HttpError(w, http.StatusInternalServerError)
 		return
 	}
@@ -66,7 +66,7 @@ func HandleBlame(w http.ResponseWriter, r *http.Request) {
 		goit.HttpError(w, http.StatusNotFound)
 		return
 	} else if err != nil {
-		util.PrintFuncError(err)
+		util.PrintError(err)
 		goit.HttpError(w, http.StatusInternalServerError)
 		return
 	}
@@ -80,7 +80,7 @@ func HandleBlame(w http.ResponseWriter, r *http.Request) {
 
 	commit, err := gr.CommitObject(ref.Hash())
 	if err != nil {
-		util.PrintFuncError(err)
+		util.PrintError(err)
 		goit.HttpError(w, http.StatusInternalServerError)
 		return
 	}
@@ -90,7 +90,7 @@ func HandleBlame(w http.ResponseWriter, r *http.Request) {
 		goit.HttpError(w, http.StatusNotFound)
 		return
 	} else if err != nil {
-		util.PrintFuncError(err)
+		util.PrintError(err)
 		goit.HttpError(w, http.StatusInternalServerError)
 		return
 	}
@@ -113,7 +113,7 @@ func HandleBlame(w http.ResponseWriter, r *http.Request) {
 
 	ftype, err := goit.GetFileType(file)
 	if err != nil {
-		util.PrintFuncError(err)
+		util.PrintError(err)
 		goit.HttpError(w, http.StatusInternalServerError)
 		return
 	}
@@ -122,7 +122,7 @@ func HandleBlame(w http.ResponseWriter, r *http.Request) {
 	if strings.HasPrefix(ftype, "text") {
 		rc, err := file.Blob.Reader()
 		if err != nil {
-			util.PrintFuncError(err)
+			util.PrintError(err)
 			goit.HttpError(w, http.StatusInternalServerError)
 			return
 		}
@@ -130,21 +130,21 @@ func HandleBlame(w http.ResponseWriter, r *http.Request) {
 
 		buf := make([]byte, min(file.Size, (10*1024*1024)))
 		if _, err := rc.Read(buf); err != nil {
-			util.PrintFuncError(err)
+			util.PrintError(err)
 			goit.HttpError(w, http.StatusInternalServerError)
 			return
 		}
 
 		body, _, err := Highlight(file.Name, string(buf), true)
 		if err != nil {
-			util.PrintFuncError(err)
+			util.PrintError(err)
 			goit.HttpError(w, http.StatusInternalServerError)
 			return
 		}
 
 		blame, err := git.Blame(commit, tpath)
 		if err != nil {
-			util.PrintFuncError(err)
+			util.PrintError(err)
 			goit.HttpError(w, http.StatusInternalServerError)
 			return
 		}
@@ -173,6 +173,6 @@ func HandleBlame(w http.ResponseWriter, r *http.Request) {
 	data.LineC = fmt.Sprint(len(data.Blines), " lines")
 
 	if err := goit.Tmpl.ExecuteTemplate(w, "repo/blame", data); err != nil {
-		util.PrintFuncError(err)
+		util.PrintError(err)
 	}
 }
diff --git a/src/repo/commit.go b/src/repo/commit.go
index 441366c..811feee 100644
--- a/src/repo/commit.go
+++ b/src/repo/commit.go
@@ -24,7 +24,7 @@ import (
 func HandleCommit(w http.ResponseWriter, r *http.Request) {
 	auth, user, err := goit.Auth(w, r, true)
 	if err != nil {
-		util.PrintFuncError(err)
+		util.PrintError(err)
 		goit.HttpError(w, http.StatusInternalServerError)
 		return
 	}
@@ -59,7 +59,7 @@ func HandleCommit(w http.ResponseWriter, r *http.Request) {
 
 	gr, err := git.PlainOpen(goit.RepoPath(repo.Name, true))
 	if err != nil {
-		util.PrintFuncError(err)
+		util.PrintError(err)
 		goit.HttpError(w, http.StatusInternalServerError)
 		return
 	}
@@ -67,7 +67,7 @@ func HandleCommit(w http.ResponseWriter, r *http.Request) {
 	ref, err := gr.Head()
 	if err != nil {
 		if !errors.Is(err, plumbing.ErrReferenceNotFound) {
-			util.PrintFuncError(err)
+			util.PrintError(err)
 			goit.HttpError(w, http.StatusInternalServerError)
 			return
 		}
@@ -85,7 +85,7 @@ func HandleCommit(w http.ResponseWriter, r *http.Request) {
 		goit.HttpError(w, http.StatusNotFound)
 		return
 	} else if err != nil {
-		util.PrintFuncError(err)
+		util.PrintError(err)
 		goit.HttpError(w, http.StatusInternalServerError)
 		return
 	}
@@ -100,7 +100,7 @@ func HandleCommit(w http.ResponseWriter, r *http.Request) {
 
 	branchCommits, err := goit.BranchCommits(gr)
 	if err != nil {
-		util.PrintFuncError(err)
+		util.PrintError(err)
 		goit.HttpError(w, http.StatusInternalServerError)
 		return
 	}
@@ -113,7 +113,7 @@ func HandleCommit(w http.ResponseWriter, r *http.Request) {
 
 	taggedCommits, err := goit.TaggedCommits(gr)
 	if err != nil {
-		util.PrintFuncError(err)
+		util.PrintError(err)
 		goit.HttpError(w, http.StatusInternalServerError)
 		return
 	}
@@ -128,7 +128,7 @@ func HandleCommit(w http.ResponseWriter, r *http.Request) {
 
 	st, err := goit.DiffStats(commit)
 	if err != nil {
-		util.PrintFuncError(err)
+		util.PrintError(err)
 		goit.HttpError(w, http.StatusInternalServerError)
 		return
 	}
@@ -172,7 +172,7 @@ func HandleCommit(w http.ResponseWriter, r *http.Request) {
 	c.Dir = goit.RepoPath(repo.Name, true)
 	out, _, err := c.Run(nil, nil)
 	if err != nil {
-		util.PrintFuncError(err)
+		util.PrintError(err)
 		goit.HttpError(w, http.StatusInternalServerError)
 		return
 	}
@@ -180,6 +180,6 @@ func HandleCommit(w http.ResponseWriter, r *http.Request) {
 	data.Diff = template.HTML(terminal.Render(out))
 
 	if err := goit.Tmpl.ExecuteTemplate(w, "repo/commit", data); err != nil {
-		util.PrintFuncError(err)
+		util.PrintError(err)
 	}
 }
diff --git a/src/repo/create.go b/src/repo/create.go
index 55d88dc..7219fe4 100644
--- a/src/repo/create.go
+++ b/src/repo/create.go
@@ -55,7 +55,7 @@ func HandleCreate(w http.ResponseWriter, r *http.Request) {
 		} else if slices.Contains(goit.Reserved, strings.SplitN(data.Name, "/", 2)[0]) || !goit.IsLegal(data.Name) {
 			data.Message = "Name \"" + data.Name + "\" is illegal"
 		} else if exists, err := goit.RepoExists(data.Name); err != nil {
-			util.PrintFuncError(err)
+			util.PrintError(err)
 			goit.HttpError(w, http.StatusInternalServerError)
 			return
 		} else if exists {
@@ -69,7 +69,7 @@ func HandleCreate(w http.ResponseWriter, r *http.Request) {
 			DefaultBranch: util.If(data.DefaultBranch == "", "master", data.DefaultBranch), Upstream: data.URL,
 			Visibility: visibility, IsMirror: data.IsMirror,
 		}); err != nil {
-			util.PrintFuncError(err)
+			util.PrintError(err)
 			goit.HttpError(w, http.StatusInternalServerError)
 			return
 		} else {
@@ -100,6 +100,6 @@ func HandleCreate(w http.ResponseWriter, r *http.Request) {
 	}
 
 	if err := goit.Tmpl.ExecuteTemplate(w, "repo/create", data); err != nil {
-		util.PrintFuncError(err)
+		util.PrintError(err)
 	}
 }
diff --git a/src/repo/file.go b/src/repo/file.go
index e0935fb..f3512c4 100644
--- a/src/repo/file.go
+++ b/src/repo/file.go
@@ -23,7 +23,7 @@ import (
 func HandleFile(w http.ResponseWriter, r *http.Request) {
 	auth, user, err := goit.Auth(w, r, true)
 	if err != nil {
-		util.PrintFuncError(err)
+		util.PrintError(err)
 		goit.HttpError(w, http.StatusInternalServerError)
 		return
 	}
@@ -52,7 +52,7 @@ func HandleFile(w http.ResponseWriter, r *http.Request) {
 
 	gr, err := git.PlainOpen(goit.RepoPath(repo.Name, true))
 	if err != nil {
-		util.PrintFuncError(err)
+		util.PrintError(err)
 		goit.HttpError(w, http.StatusInternalServerError)
 		return
 	}
@@ -62,7 +62,7 @@ func HandleFile(w http.ResponseWriter, r *http.Request) {
 		goit.HttpError(w, http.StatusNotFound)
 		return
 	} else if err != nil {
-		util.PrintFuncError(err)
+		util.PrintError(err)
 		goit.HttpError(w, http.StatusInternalServerError)
 		return
 	}
@@ -76,7 +76,7 @@ func HandleFile(w http.ResponseWriter, r *http.Request) {
 
 	commit, err := gr.CommitObject(ref.Hash())
 	if err != nil {
-		util.PrintFuncError(err)
+		util.PrintError(err)
 		goit.HttpError(w, http.StatusInternalServerError)
 		return
 	}
@@ -86,7 +86,7 @@ func HandleFile(w http.ResponseWriter, r *http.Request) {
 		goit.HttpError(w, http.StatusNotFound)
 		return
 	} else if err != nil {
-		util.PrintFuncError(err)
+		util.PrintError(err)
 		goit.HttpError(w, http.StatusInternalServerError)
 		return
 	}
@@ -109,7 +109,7 @@ func HandleFile(w http.ResponseWriter, r *http.Request) {
 
 	ftype, err := goit.GetFileType(file)
 	if err != nil {
-		util.PrintFuncError(err)
+		util.PrintError(err)
 		goit.HttpError(w, http.StatusInternalServerError)
 		return
 	}
@@ -118,7 +118,7 @@ func HandleFile(w http.ResponseWriter, r *http.Request) {
 	if strings.HasPrefix(ftype, "text") {
 		rc, err := file.Blob.Reader()
 		if err != nil {
-			util.PrintFuncError(err)
+			util.PrintError(err)
 			goit.HttpError(w, http.StatusInternalServerError)
 			return
 		}
@@ -126,14 +126,14 @@ func HandleFile(w http.ResponseWriter, r *http.Request) {
 
 		buf := make([]byte, min(file.Size, (10*1024*1024)))
 		if _, err := rc.Read(buf); err != nil {
-			util.PrintFuncError(err)
+			util.PrintError(err)
 			goit.HttpError(w, http.StatusInternalServerError)
 			return
 		}
 
 		body, css, err := Highlight(file.Name, string(buf), false)
 		if err != nil {
-			util.PrintFuncError(err)
+			util.PrintError(err)
 			goit.HttpError(w, http.StatusInternalServerError)
 			return
 		}
@@ -147,6 +147,6 @@ func HandleFile(w http.ResponseWriter, r *http.Request) {
 	data.LineC = fmt.Sprint(len(data.Lines), " lines")
 
 	if err := goit.Tmpl.ExecuteTemplate(w, "repo/file", data); err != nil {
-		util.PrintFuncError(err)
+		util.PrintError(err)
 	}
 }
diff --git a/src/repo/log.go b/src/repo/log.go
index f6d50db..9f3b90e 100644
--- a/src/repo/log.go
+++ b/src/repo/log.go
@@ -25,7 +25,7 @@ const PAGE = 100
 func HandleLog(w http.ResponseWriter, r *http.Request) {
 	auth, user, err := goit.Auth(w, r, true)
 	if err != nil {
-		util.PrintFuncError(err)
+		util.PrintError(err)
 		goit.HttpError(w, http.StatusInternalServerError)
 		return
 	}
@@ -72,7 +72,7 @@ func HandleLog(w http.ResponseWriter, r *http.Request) {
 
 	gr, err := git.PlainOpen(goit.RepoPath(repo.Name, true))
 	if err != nil {
-		util.PrintFuncError(err)
+		util.PrintError(err)
 		goit.HttpError(w, http.StatusInternalServerError)
 		return
 	}
@@ -82,7 +82,7 @@ func HandleLog(w http.ResponseWriter, r *http.Request) {
 		data.NextOffset = 0
 		goto execute
 	} else if err != nil {
-		util.PrintFuncError(err)
+		util.PrintError(err)
 		goit.HttpError(w, http.StatusInternalServerError)
 		return
 	}
@@ -99,7 +99,7 @@ func HandleLog(w http.ResponseWriter, r *http.Request) {
 			return tpath == "" || s == tpath || strings.HasPrefix(s, tpath+"/")
 		},
 	}); err != nil {
-		util.PrintFuncError(err)
+		util.PrintError(err)
 		goit.HttpError(w, http.StatusInternalServerError)
 		return
 	} else {
@@ -110,7 +110,7 @@ func HandleLog(w http.ResponseWriter, r *http.Request) {
 					goto execute
 				}
 
-				util.PrintFuncError(err)
+				util.PrintError(err)
 				goit.HttpError(w, http.StatusInternalServerError)
 				return
 			}
@@ -118,7 +118,7 @@ func HandleLog(w http.ResponseWriter, r *http.Request) {
 
 		taggedCommits, err := goit.TaggedCommits(gr)
 		if err != nil {
-			util.PrintFuncError(err)
+			util.PrintError(err)
 			goit.HttpError(w, http.StatusInternalServerError)
 			return
 		}
@@ -129,7 +129,7 @@ func HandleLog(w http.ResponseWriter, r *http.Request) {
 				data.NextOffset = 0
 				goto execute
 			} else if err != nil {
-				util.PrintFuncError(err)
+				util.PrintError(err)
 				goit.HttpError(w, http.StatusInternalServerError)
 				return
 			}
@@ -137,7 +137,7 @@ func HandleLog(w http.ResponseWriter, r *http.Request) {
 			var files, additions, deletions int
 
 			if stats, err := goit.DiffStats(c); err != nil {
-				util.PrintFuncError(err)
+				util.PrintError(err)
 			} else {
 				files = len(stats)
 				for _, s := range stats {
@@ -167,6 +167,6 @@ func HandleLog(w http.ResponseWriter, r *http.Request) {
 
 execute:
 	if err := goit.Tmpl.ExecuteTemplate(w, "repo/log", data); err != nil {
-		util.PrintFuncError(err)
+		util.PrintError(err)
 	}
 }
diff --git a/src/repo/refs.go b/src/repo/refs.go
index 00fd0b5..a10710f 100644
--- a/src/repo/refs.go
+++ b/src/repo/refs.go
@@ -21,7 +21,7 @@ import (
 func HandleRefs(w http.ResponseWriter, r *http.Request) {
 	auth, user, err := goit.Auth(w, r, true)
 	if err != nil {
-		util.PrintFuncError(err)
+		util.PrintError(err)
 		goit.HttpError(w, http.StatusInternalServerError)
 		return
 	}
@@ -50,7 +50,7 @@ func HandleRefs(w http.ResponseWriter, r *http.Request) {
 
 	gr, err := git.PlainOpen(goit.RepoPath(repo.Name, true))
 	if err != nil {
-		util.PrintFuncError(err)
+		util.PrintError(err)
 		goit.HttpError(w, http.StatusInternalServerError)
 		return
 	}
@@ -58,7 +58,7 @@ func HandleRefs(w http.ResponseWriter, r *http.Request) {
 	ref, err := gr.Head()
 	if err != nil {
 		if !errors.Is(err, plumbing.ErrReferenceNotFound) {
-			util.PrintFuncError(err)
+			util.PrintError(err)
 			goit.HttpError(w, http.StatusInternalServerError)
 			return
 		}
@@ -72,7 +72,7 @@ func HandleRefs(w http.ResponseWriter, r *http.Request) {
 	}
 
 	if iter, err := gr.Branches(); err != nil {
-		util.PrintFuncError(err)
+		util.PrintError(err)
 		goit.HttpError(w, http.StatusInternalServerError)
 		return
 	} else if err := iter.ForEach(func(r *plumbing.Reference) error {
@@ -93,14 +93,14 @@ func HandleRefs(w http.ResponseWriter, r *http.Request) {
 
 		return nil
 	}); err != nil {
-		util.PrintFuncError(err)
+		util.PrintError(err)
 		goit.HttpError(w, http.StatusInternalServerError)
 		return
 	}
 
 	tags, err := goit.TaggedCommits(gr)
 	if err != nil {
-		util.PrintFuncError(err)
+		util.PrintError(err)
 		goit.HttpError(w, http.StatusInternalServerError)
 		return
 	}
@@ -116,6 +116,6 @@ func HandleRefs(w http.ResponseWriter, r *http.Request) {
 	slices.Reverse(data.Tags)
 
 	if err := goit.Tmpl.ExecuteTemplate(w, "repo/refs", data); err != nil {
-		util.PrintFuncError(err)
+		util.PrintError(err)
 	}
 }
diff --git a/src/repo/tag.go b/src/repo/tag.go
index 4142c19..9955d03 100644
--- a/src/repo/tag.go
+++ b/src/repo/tag.go
@@ -20,7 +20,7 @@ import (
 func HandleTag(w http.ResponseWriter, r *http.Request) {
 	auth, user, err := goit.Auth(w, r, true)
 	if err != nil {
-		util.PrintFuncError(err)
+		util.PrintError(err)
 		goit.HttpError(w, http.StatusInternalServerError)
 		return
 	}
@@ -47,7 +47,7 @@ func HandleTag(w http.ResponseWriter, r *http.Request) {
 
 	gr, err := git.PlainOpen(goit.RepoPath(repo.Name, true))
 	if err != nil {
-		util.PrintFuncError(err)
+		util.PrintError(err)
 		goit.HttpError(w, http.StatusInternalServerError)
 		return
 	}
@@ -55,7 +55,7 @@ func HandleTag(w http.ResponseWriter, r *http.Request) {
 	head, err := gr.Head()
 	if err != nil {
 		if !errors.Is(err, plumbing.ErrReferenceNotFound) {
-			util.PrintFuncError(err)
+			util.PrintError(err)
 			goit.HttpError(w, http.StatusInternalServerError)
 			return
 		}
@@ -73,7 +73,7 @@ func HandleTag(w http.ResponseWriter, r *http.Request) {
 		goit.HttpError(w, http.StatusNotFound)
 		return
 	} else if err != nil {
-		util.PrintFuncError(err)
+		util.PrintError(err)
 		goit.HttpError(w, http.StatusInternalServerError)
 		return
 	}
@@ -83,14 +83,14 @@ func HandleTag(w http.ResponseWriter, r *http.Request) {
 	var commit *object.Commit
 	if tag, err := gr.TagObject(ref.Hash()); err != nil {
 		if !errors.Is(err, plumbing.ErrObjectNotFound) {
-			util.PrintFuncError(err)
+			util.PrintError(err)
 			goit.HttpError(w, http.StatusInternalServerError)
 			return
 		}
 
 		/* Tag is not annotated. */
 		if commit, err = gr.CommitObject(ref.Hash()); err != nil {
-			util.PrintFuncError(err)
+			util.PrintError(err)
 			goit.HttpError(w, http.StatusInternalServerError)
 			return
 		}
@@ -100,7 +100,7 @@ func HandleTag(w http.ResponseWriter, r *http.Request) {
 	} else {
 		/* Tag is annotated. */
 		if commit, err = gr.CommitObject(tag.Target); err != nil {
-			util.PrintFuncError(err)
+			util.PrintError(err)
 			goit.HttpError(w, http.StatusInternalServerError)
 			return
 		}
@@ -113,6 +113,6 @@ func HandleTag(w http.ResponseWriter, r *http.Request) {
 	data.Commit = commit.Hash.String()
 
 	if err := goit.Tmpl.ExecuteTemplate(w, "repo/tag", data); err != nil {
-		util.PrintFuncError(err)
+		util.PrintError(err)
 	}
 }
diff --git a/src/user/keys.go b/src/user/keys.go
index 91845ee..429e6de 100644
--- a/src/user/keys.go
+++ b/src/user/keys.go
@@ -19,7 +19,7 @@ import (
 func HandleKeys(w http.ResponseWriter, r *http.Request) {
 	auth, user, err := goit.Auth(w, r, true)
 	if err != nil {
-		util.PrintFuncError(err)
+		util.PrintError(err)
 		goit.HttpError(w, http.StatusInternalServerError)
 		return
 	}
@@ -44,13 +44,13 @@ func HandleKeys(w http.ResponseWriter, r *http.Request) {
 		if r.FormValue("submit") == "Delete" {
 			kid, err := strconv.ParseInt(r.FormValue("kid"), 10, 64)
 			if err != nil {
-				util.PrintFuncError(err)
+				util.PrintError(err)
 				goit.HttpError(w, http.StatusInternalServerError)
 				return
 			}
 
 			if err := goit.DelKey(kid); err != nil {
-				util.PrintFuncError(err)
+				util.PrintError(err)
 				goit.HttpError(w, http.StatusInternalServerError)
 				return
 			}
@@ -62,7 +62,7 @@ func HandleKeys(w http.ResponseWriter, r *http.Request) {
 	}
 
 	if keys, err := goit.GetKeys(user.Id); err != nil {
-		util.PrintFuncError(err)
+		util.PrintError(err)
 		goit.HttpError(w, http.StatusInternalServerError)
 		return
 	} else {
@@ -72,7 +72,7 @@ func HandleKeys(w http.ResponseWriter, r *http.Request) {
 	for _, key := range data.Keys {
 		k, err := ssh.ParsePublicKey(key.Key)
 		if err != nil {
-			util.PrintFuncError(err)
+			util.PrintError(err)
 			goit.HttpError(w, http.StatusInternalServerError)
 			return
 		}
@@ -80,14 +80,14 @@ func HandleKeys(w http.ResponseWriter, r *http.Request) {
 	}
 
 	if err := goit.Tmpl.ExecuteTemplate(w, "user/keys", data); err != nil {
-		util.PrintFuncError(err)
+		util.PrintError(err)
 	}
 }
 
 func HandleKeysAdd(w http.ResponseWriter, r *http.Request) {
 	auth, user, err := goit.Auth(w, r, true)
 	if err != nil {
-		util.PrintFuncError(err)
+		util.PrintError(err)
 		goit.HttpError(w, http.StatusInternalServerError)
 		return
 	}
@@ -121,7 +121,7 @@ func HandleKeysAdd(w http.ResponseWriter, r *http.Request) {
 		} else if err := goit.AddKey(goit.Key{
 			OwnerID: user.Id, Description: comment, Key: key.Marshal(), Type: goit.SSH_Auth,
 		}); err != nil {
-			util.PrintFuncError(err)
+			util.PrintError(err)
 			goit.HttpError(w, http.StatusInternalServerError)
 			return
 		} else {
@@ -132,6 +132,6 @@ func HandleKeysAdd(w http.ResponseWriter, r *http.Request) {
 	}
 
 	if err := goit.Tmpl.ExecuteTemplate(w, "user/keys/add", data); err != nil {
-		util.PrintFuncError(err)
+		util.PrintError(err)
 	}
 }
diff --git a/src/util/log.go b/src/util/log.go
index 047f40f..c326135 100644
--- a/src/util/log.go
+++ b/src/util/log.go
@@ -10,7 +10,7 @@ import (
 
 var Debug = false
 
-func PrintFuncError(err error) {
+func PrintError(err error) {
 	pc, _, ln, ok := runtime.Caller(1)
 	if !ok {
 		log.Println(err)