blob: ac9248f15852829c54eb1d38132e3ed712aeaa2f (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
|
#!/usr/bin/env fish
# load environment
source (status dirname)/env
#
#
# function definitions
#
#
function fail
set_color red
echo "$argv"
set_color normal
return 1
end
function checkUser
set -l user $argv[1]
cat /etc/passwd | grep -q -E "^$user:"
return $status
end
function setupUser
set -l userConfig (string split ':' $argv[1])
set -l user $userConfig[1]
set -l key $userConfig[2]
set -l HOME "/home/$user"
echo "Setting up user: $user"
if [ "$user" = git ]
echo "Error: User git is reserved"
return 1
end
# setup user exist if necessary
if not checkUser "$user"
# user is not restricted, this is done in ssh config with forceCommand
# we need to be able to run a fish script to check for permissions
adduser --home $HOME -D "$user"; or fail "Failed to create user $user"
# add user to sudo group
addgroup "$user" $_GIT_SUDO_GROUP; or fail "Failed to add user $user to group $_GIT_SUDO_GROUP"
# unlock account to allow ssh logins
passwd -u "$user" &>/dev/null; or fail "Failed to unlock account of $user"
end
# Copy/Overwrite ssh key
mkdir "$HOME/.ssh"
echo "$key" > "$HOME/.ssh/authorized_keys"
chown -R $user "$HOME"
chmod -R 700 "$HOME"
end
function setupGitUser
checkUser "git"; and return 0
echo "Setting up git user"
# git user has read/write access to all repos, set git-shell
# and no password login allowed -> no ssh login possible
addgroup -g $GIT_GID git; or fail "Failed to create git user group"
adduser git -u $GIT_UID -G git -D --shell "/usr/bin/git-shell"; or fail "Failed to setup git user"
# group that is allowed to sudo
addgroup $_GIT_SUDO_GROUP; or fail "Failed to setup git sudo group"
end
function setupRepo
set -l repoConfig $argv[1]
set -l parsedConfig (string split ';' -- $repoConfig)
set -l repo $parsedConfig[1]
# check repo name
set -l matcher (string match -r -g "^$_REPO_VALIDATION_REGEX\$" -- $repo)
if test -z $matcher[1]
fail "Failed to setup repo, invalid config: $repoConfig"
return 1
end
# we assume all repos to be in /srv/repos
set -l repoDir srv repos
set repoDir /(string join -n '/' $repoDir (string split '/' $repo))
echo "Setting up repo: $repo"
# write user as allowed into permission file
for userConfig in $parsedConfig[2..]
set -l parsedConfig (string split ':' -- $userConfig)
set -l user $parsedConfig[1]
set -l permission $parsedConfig[2]
# check for valid permission
if not contains $permission $_PERMISSIONS
set permission "r"
end
echo "$repoDir:$user:$permission" >> $_REPO_PERMISSIONS_FILE
end
# setup repo dir
if not test -d $repoDir
mkdir -p $repoDir
git init --bare $repoDir -b trunk
end
chown -R git:git "$repoDir"
chmod -R 700 "$repoDir"
end
function runSSHDaemon
echo "Setting up server"
# generate host keys in case
mkdir -p /var/ssh/etc/ssh/ && ssh-keygen -A -f /var/ssh
# run ssh daemon
/usr/sbin/sshd -D -e
end
#
#
# main
#
#
argparse 'g/git-uid=?' 'u/user=+' 'r/repo=+' 'h/help' 'v/version' -- $argv
or exit 1;
if set -q _flag_h
echo "Usage: $(status filename) [ OPTIONS ]..."
echo -e ""
echo -e "OPTIONS"
echo -e "\t -h, --help \t\t Display this page"
echo -e "\t -g, --git-uid \t\t UID of the git user that is used also as ownership for all repos"
echo -e "\t -u, --user \t\t User setting in form of <user-name>:<public-key>"
echo -e "\t -r, --repo \t\t Repo setting in form of <repo-path>;<user>:<perm>[;<user2>:<perm>;...]. You can add as many users as you want. If you do not specify a user for a repo, that user does not have access to it. If you specify a user without permission, the default fallback is read only."
echo -e "\t -v, --version \t\t Version"
echo -e ""
return
end
if set -q _flag_v
echo -e "$_VERSION"
return
end
function showBanner
echo
echo '
_ _
__ _(_) |_ ___ ___ _ ____ _____ _ __
/ _` | | __|____/ __|/ _ \ '__\ \ / / _ \ '__|
| (_| | | ||_____\__ \ __/ | \ V / __/ |
\__, |_|\__| |___/\___|_| \_/ \___|_|
|___/
'
echo
echo Copyright Matthias Jaros 2025
echo This software is licensed under GPLv3. See /usr/share/doc/git-server/LICENSE
echo
end
showBanner
# read variables
set -l users $_flag_u
for user in (set -n | string match -r "^USER_\S+")
set users $users (eval echo \$$user)
end
set -l repos $_flag_r
for repo in (set -n | string match -r "^REPO_\S+")
set repos $repos (eval echo \$$repo)
end
if set -q $_flag_g
set GIT_UID $_flag_g
end
# Setup users
setupGitUser
for userConfig in $users
setupUser "$userConfig"
end
# Setup repos
echo > $_REPO_PERMISSIONS_FILE
for repoConfig in $repos
setupRepo "$repoConfig"
end
# create writable log file for run script
touch $_LOG && chmod 777 $_LOG
runSSHDaemon
|