names: tighten up the requirements for project and user names
[girocco.git] / Girocco / Config.pm
blobad6321b62c9c640430a95e98e379e9b8bd7ad106
1 package Girocco::Config;
3 use strict;
4 use warnings;
7 ## Basic settings
9 # Name of the service
10 our $name = "GiroccoEx";
12 # Nickname of the service (undef for initial part of $name upto first '.')
13 our $nickname = undef;
15 # Title of the service (as shown in gitweb)
16 our $title = "Example Girocco Hosting";
18 # Path to the Git binary to use (you MUST set this, even if to /usr/bin/git!)
19 our $git_bin = '/usr/bin/git';
21 # Path to the git-http-backend binary to use (undef to use /usr/lib/git-core/git-http-backend)
22 # If both $httppullurl and $httpspushurl are undef this will never be used
23 # This should usually be set to `printf %s \$($git_bin --exec-path)/git-http-backend`
24 # which is to say the git-http-backend binary located in the --exec-path directory of $git_bin.
25 our $git_http_backend_bin = undef;
27 # Name (if in $PATH) or full path to netcat executable that accepts a -U option
28 # to connect to a unix socket. This may simply be 'nc' on many systems.
29 our $nc_openbsd_bin = 'nc.openbsd';
31 # Path to the sendmail instance to use. It should understand the -f <from>, -i and -t
32 # options as well as accepting a list of recipient addresses in order to be used here.
33 # You MUST set this, even if to '/usr/sbin/sendmail'!
34 # Setting this to 'sendmail.pl' is special and will automatically be expanded to
35 # a full path to the ../bin/sendmail.pl executable in this Girocco installation.
36 # sendmail.pl is a sendmail-compatible script that delivers the message directly
37 # using SMTP to a mail relay host. This is the recommended configuration as it
38 # minimizes the information exposed to recipients (no sender account names or uids),
39 # can talk to an SMTP server on another host (eliminating the need for a working
40 # sendmail and/or SMTP server on this host) and avoids any unwanted address rewriting.
41 # By default it expects the mail relay to be listening on localhost port 25.
42 # See the sendmail.pl section below for more information on configuring sendmail.pl.
43 our $sendmail_bin = 'sendmail.pl';
45 # E-mail of the site admin
46 our $admin = 'admin@example.org';
48 # Sender of emails
49 # This is the SMTP 'MAIL FROM:' value
50 # It will be passed to $sendmail_bin with the -f option
51 # Some sites may not allow non-privileged users to pass the -f option to
52 # $sendmail_bin. In that case set this to undef and no -f option will be
53 # passed which means the 'MAIL FROM:' value will be the user the mail is
54 # sent as (either $cgi_user or $mirror_user depending on the activity).
55 # To avoid having bounce emails go to $admin, this may be set to something
56 # else such as 'admin-noreply@example.org' and then the 'admin-noreply' address
57 # may be redirected to /dev/null. Setting this to '' or '<>' is not
58 # recommended because that will likely cause the emails to be marked as SPAM
59 # by the receiver's SPAM filter. If $sendmail_bin is set to 'sendmail.pl' this
60 # value must be acceptable to the receiving SMTP server as a 'MAIL FROM:' value.
61 # If this is set to undef and 'sendmail.pl' is used, the 'MAIL FROM:' value will
62 # be the user the mail is sent as (either $cgi_user or $mirror_user).
63 our $sender = $admin;
65 # Copy $admin on failure/recovery messages?
66 our $admincc = 1;
68 # Girocco branch to use for html.cgi view source links (undef for HEAD)
69 our $giroccobranch = undef;
72 ## Feature knobs
74 # Enable mirroring mode if true (see "Foreign VCS mirrors" section below)
75 our $mirror = 1;
77 # Enable push mode if true
78 our $push = 1;
80 # If both $mirror and $push are enabled, setting this to 'mirror' pre-selects
81 # mirror mode on the initial regproj display, otherwise 'push' mode will be
82 # pre-selected. When forking the initial mode will be 'push' if $push enabled.
83 our $initial_regproj_mode = 'mirror';
85 # Enable user management if true; this means the interface for registering
86 # user accounts and uploading SSH keys. This implies full chroot.
87 our $manage_users = 1;
89 # Minimum key length (in bits) for uploaded SSH RSA/DSA keys.
90 # If this is not set (i.e. undef) keys as small as 512 bits will be allowed.
91 # Nowadays keys less than 2048 bits in length should probably not be allowed.
92 # Note, however, that versions of OpenSSH starting with 4.3p1 will only generate
93 # DSA keys of exactly 1024 bits in length even though that length is no longer
94 # recommended. (OpenSSL can be used to generate DSA keys with lengths > 1024.)
95 # OpenSSH does not have any problem generating RSA keys longer than 1024 bits.
96 # This setting is only checked when new keys are added so setting it/increasing it
97 # will not affect existing keys. For maximum compatibility a value of 1024 may
98 # be used however 2048 is recommended. Setting it to anything other than 1024,
99 # 2048 or 3072 may have the side effect of making it very difficult to generate
100 # DSA keys that satisfy the restriction (but RSA keys should not be a problem).
101 # Note that no matter what setting is specified here keys smaller than 512 bits
102 # will never be allowed via the reguser.cgi/edituser.cgi interface.
103 # RECOMMENDED VALUE: 2048 (ok) or 3072 (better)
104 our $min_key_length = 1024;
106 # Disable DSA public keys?
107 # If this is set to 1, adding DSA keys at reguser.cgi/edituser.cgi time will be
108 # prohibited. If $pushurl is undef then this is implicitly set to 1 since DSA
109 # keys are not usable with https push.
110 # OpenSSH will only generate 1024 bit DSA keys starting with version 4.3p1.
111 # Even if OpenSSL is used to generate a longer DSA key (which can then be used
112 # with OpenSSH), the SSH protocol itself still forces use of SHA-1 in the DSA
113 # signature blob which tends to defeat the purpose of going to a longer key in
114 # the first place. So it may be better from a security standpoint to simply
115 # disable DSA keys especially if $min_key_length and $rsakeylength have been set
116 # to something higher such as 3072 or 4096. This setting is only checked when
117 # new keys are added so setting it/increasing it will not affect existing keys.
118 # There is no way to disable DSA keys in the OpenSSH server config file itself.
119 # If this is set to 1, no ssh_host_dsa_key will be generated or used with the
120 # sshd running in the jail (but if the sshd_config has already been generated
121 # in the jail, it must be removed and 'sudo make install' run again or otherwise
122 # the sshd_config needs to be edited by hand for the change to take effect).
123 # RECOMMENDED VALUE: 1
124 our $disable_dsa = 0;
126 # Enable the special 'mob' user if set to 'mob'
127 our $mob = "mob";
129 # Let users set admin passwords; if false, all password inputs are assumed empty.
130 # This will make new projects use empty passwords and all operations on them
131 # unrestricted, but you will be able to do no operations on previously created
132 # projects you have set a password on.
133 our $project_passwords = 1;
135 # How to determine project owner; 'email' adds a form item asking for their
136 # email contact, 'source' takes realname of owner of source repository if it
137 # is a local path (and empty string otherwise). 'source' is suitable in case
138 # the site operates only as mirror of purely local-filesystem repositories.
139 our $project_owners = 'email';
141 # Which project fields to make editable, out of 'shortdesc', 'homepage',
142 # 'README', 'notifymail', 'notifyjson', 'notifycia'. (This is currently
143 # soft restriction - form fields aren't used, but manually injected values
144 # *are* used. Submit a patch if that's an issue for you.)
145 our @project_fields = qw(homepage shortdesc README notifymail notifyjson notifycia);
147 # Minimal number of seconds to pass between two updates of a project.
148 our $min_mirror_interval = 3600; # 1 hour
150 # Minimal number of seconds to pass between two garbage collections of a project.
151 our $min_gc_interval = 604800; # 1 week
153 # Whether or not to run the ../bin/update-pwd-db script whenever the etc/passwd
154 # database is changed. This is typically needed (i.e. set to a true value) for
155 # FreeBSD style systems when using an sshd chroot jail for push access. So if
156 # $pushurl is undef or the system Girocco is running on is not like FreeBSD
157 # (e.g. a master.passwd file that must be transformed into pwd.db and spwd.db), then
158 # this setting should normally be left false (i.e. 0). See comments in the
159 # provided ../bin/update-pwd-db script about when and how it's invoked.
160 our $update_pwd_db = 0;
162 # Port the sshd running in the jail should listen on
163 # Be sure to update $pushurl to match
164 # Not used if $pushurl is undef
165 our $sshd_jail_port = 22;
167 # If this is true then host names used in mirror source URLs will be checked
168 # and any that are not DNS names (i.e. IPv4 or IPv6) or match one of the DNS
169 # host names in any of the URL settings below will be rejected.
170 our $restrict_mirror_hosts = 1;
172 # If $restrict_mirror_hosts is enabled this is the minimum number of labels
173 # required in a valid dns name. Normally 2 is the correct value, but if
174 # Girocco is being used internally where a common default or search domain
175 # is set for everyone then this should be changed to 1 to allow a dns name
176 # with a single label in it. No matter what is set here at least 1 label
177 # is always required when $restrict_mirror_hosts is enabled.
178 our $min_dns_labels = 2;
181 ## Foreign VCS mirrors
183 # Note that if any of these settings are changed from true to false, then
184 # any pre-existing mirrors using the now-disabled foreign VCS will stop
185 # updating, new mirrors using the now-disabled foreign VCS will be disallowed
186 # and attempts to update ANY project settings for a pre-existing project that
187 # uses a now-disabled foreign VCS source URL will also be disallowed.
189 # If $mirror is true and $mirror_svn is true then mirrors from svn source
190 # repositories will be allowed (and be converted to Git). These URLs have
191 # the form svn://... or svn+http://... or svn+https://...
192 # Note that for this to work the "svn" command line command must be available
193 # in PATH and the "git svn" commands must work (which generally requires both
194 # Perl and the subversion perl bindings be installed).
195 our $mirror_svn = 1;
197 # If $mirror is true and $mirror_darcs is true then mirrors from darcs source
198 # repositories will be allowed (and be converted to Git). These URLs have
199 # the form darcs://...
200 # Note that for this to work the "darcs" command line command must be available
201 # in PATH and so must python (required to run the darcs-fast-export script).
202 our $mirror_darcs = 1;
204 # If $mirror is true and $mirror_bzr is true then mirrors from bzr source
205 # repositories will be allowed (and be converted to Git). These URLs have
206 # the form bzr://...
207 # Note that for this to work the "bzr" command line command must be available
208 # in PATH (it's a python script so python is required as well).
209 our $mirror_bzr = 1;
211 # If $mirror is true and $mirror_hg is true then mirrors from hg source
212 # repositories will be allowed (and be converted to Git). These URLs have
213 # the form hg+http://... or hg+https://...
214 # Note that for this to work the "hg" command line command must be available
215 # in PATH and so must python (required to run the hg-fast-export.py script).
216 # Note that if the PYTHON environment variable is set that will be used instead
217 # of just plain "python" to run the hg-fast-export.py script (which needs to
218 # be able to import from mercurial).
219 our $mirror_hg = 1;
222 ## Paths
224 # Path where the main chunk of Girocco files will be installed
225 # This will get COMPLETELY OVERWRITTEN by each make install!!!
226 our $basedir = '/home/repo/repomgr';
228 # Path where the automatically generated non-user certificates will be stored
229 # (The per-user certificates are always stored in $chroot/etc/sshcerts/)
230 # This is preserved by each make install and MUST NOT be under $basedir!
231 # Not used unless $httpspushurl is defined
232 our $certsdir = '/home/repo/certs';
234 # The repository collection
235 # "$reporoot-recyclebin" will also be created for use by toolbox/trash-project.pl
236 our $reporoot = "/srv/git";
238 # The repository collection's location within the chroot jail
239 # Normally $reporoot will be bind mounted onto $chroot/$jailreporoot
240 # Should NOT start with '/'
241 our $jailreporoot = "srv/git";
243 # The chroot for ssh pushing; location for project database and other run-time
244 # data even in non-chroot setups
245 our $chroot = "/home/repo/j";
247 # The gitweb files web directory (corresponds to $gitwebfiles)
248 our $webroot = "/home/repo/WWW";
250 # The CGI-enabled web directory (corresponds to $gitweburl and $webadmurl)
251 our $cgiroot = "/home/repo/WWW";
253 # A web-accessible symlink to $reporoot (corresponds to $httppullurl, can be undef)
254 # If using the sample apache.conf (with paths suitably updated) this is not required
255 # to serve either smart or non-smart HTTP repositories to the Git client
256 our $webreporoot = "/home/repo/WWW/r";
259 ## Certificates (only used if $httpspushurl is defined)
261 # path to root certificate (undef to use automatic root cert)
262 # this certificate is made available for easy download and should be whatever
263 # the root certificate is for the https certificate being used by the web server
264 our $rootcert = undef;
266 # The certificate to sign user push client authentication certificates with (undef for auto)
267 # The automatically generated certificate should always be fine
268 our $clientcert = undef;
270 # The private key for $clientcert (undef for auto)
271 # The automatically generated key should always be fine
272 our $clientkey = undef;
274 # The client certificate chain suffix (a pemseq file to append to user client certs) (undef for auto)
275 # The automatically generated chain should always be fine
276 # This suffix will also be appended to the $mobusercert before making it available for download
277 our $clientcertsuffix = undef;
279 # The mob user certificate signed by $clientcert (undef for auto)
280 # The automatically generated certificate should always be fine
281 # Not used unless $mob is set to 'mob'
282 # The $clientcertsuffix will be appended before making $mobusercert available for download
283 our $mobusercert = undef;
285 # The private key for $mobusercert (undef for auto)
286 # The automatically generated key should always be fine
287 # Not used unless $mob is set to 'mob'
288 our $mobuserkey = undef;
290 # The key length for automatically generated RSA private keys (in bits).
291 # These keys are then used to create the automatically generated certificates.
292 # If undef or set to a value less than 2048, then 2048 will be used.
293 # Set to 3072 to generate more secure keys/certificates. Set to 4096 (or higher) for
294 # even greater security. Be warned that setting to a non-multiple of 8 and/or greater
295 # than 4096 could negatively impact compatibility with some clients.
296 # The values 2048, 3072 and 4096 are expected to be compatible with all clients.
297 # Note that OpenSSL has no problem with > 4096 or non-multiple of 8 lengths.
298 # See also the $min_key_length setting above to restrict user key sizes.
299 # This value is also used when generating the ssh_host_rsa_key for the chroot jail sshd.
300 # RECOMMENDED VALUE: 3072
301 our $rsakeylength = undef;
304 ## URL addresses
306 # URL of the gitweb.cgi script (must be in pathinfo mode)
307 # If mod_rewrite is enabled and the sample apache.conf configuration is used
308 # (with paths suitably updated), the trailing "/w" is optional for all browsers
309 # that send a User-Agent string WITHOUT (case insensitively) "git/". Alternatively
310 # a minor change to the sample apache.conf can redirect (301 or 302) URLs without
311 # the "/w" to a URL with it where appropriate.
312 our $gitweburl = "http://repo.or.cz/w";
314 # URL of the extra gitweb files (CSS, .js files, images, ...)
315 our $gitwebfiles = "http://repo.or.cz";
317 # URL of the Girocco CGI web admin interface (Girocco cgi/ subdirectory)
318 our $webadmurl = "http://repo.or.cz";
320 # URL of the Girocco CGI html templater (Girocco cgi/html.cgi)
321 our $htmlurl = "http://repo.or.cz/h";
323 # HTTP URL of the repository collection (undef if N/A)
324 # If mod_rewrite is enabled and the sample apache.conf configuration is used
325 # (with paths suitably updated), the trailing "/r" is optional for Git clients
326 # that send a User-Agent string containing "git/" (case insensitively).
327 our $httppullurl = "http://repo.or.cz/r";
329 # HTTPS push URL of the repository collection (undef if N/A)
330 # If this is defined, the openssl command must be available
331 # The sample apache.conf configuration requires mod_rewrite be enabled to
332 # support https push operations.
333 # Normally this should be set to $httppullurl with http: replaced with https:
334 # If the sample apache.conf configuration is used (with paths suitably updated),
335 # the trailing "/r" is optional for Git clients that send a User-Agent string
336 # containing "git/" (case insensitively).
337 our $httpspushurl = undef;
339 # Git URL of the repository collection (undef if N/A)
340 # (You need to set up git-daemon on your system, and Girocco will not
341 # do this particular thing for you.)
342 our $gitpullurl = "git://repo.or.cz";
344 # Pushy SSH URL of the repository collection (undef if N/A)
345 # Note that the "/$jailreporoot" portion is optional and will be automatically
346 # added if appropriate when omitted by the client so this URL can typically
347 # be made the same as $gitpullurl with git: replaced with ssh:
348 our $pushurl = "ssh://repo.or.cz/$jailreporoot";
350 # URL of gitweb of this Girocco instance (set to undef if you're not nice
351 # to the community)
352 our $giroccourl = "$Girocco::Config::gitweburl/girocco.git";
355 ## Some templating settings
357 # Legal warning (on reguser and regproj pages)
358 our $legalese = <<EOT;
359 <p>By submitting this form, you are confirming that you will mirror or push
360 only what we can store and show to anyone else who can visit this site without
361 breaking any law, and that you will be nice to all small furry animals.
362 <sup><a href="/h/about.html">(more details)</a></sup>
363 </p>
366 # Pre-configured mirror sources (set to undef for none)
367 # Arrayref of name - record pairs, the record has these attributes:
368 # label: The label of this source
369 # url: The template URL; %1, %2, ... will be substituted for inputs
370 # desc: Optional VERY short description
371 # link: Optional URL to make the desc point at
372 # inputs: Arrayref of hashref input records:
373 # label: Label of input record
374 # suffix: Optional suffix
375 # If the inputs arrayref is undef, single URL input is shown,
376 # pre-filled with url (probably empty string).
377 our $mirror_sources = [
379 label => 'Anywhere',
380 url => '',
381 desc => 'Any HTTP/Git/rsync pull URL - bring it on!',
382 inputs => undef
385 label => 'GitHub',
386 url => 'git://github.com/%1/%2.git',
387 desc => 'GitHub Social Code Hosting',
388 link => 'http://github.com/',
389 inputs => [ { label => 'User:' }, { label => 'Project:', suffix => '.git' } ]
392 label => 'Gitorious',
393 url => 'git://gitorious.org/%1/%2.git',
394 desc => 'Green and Orange Boxes',
395 link => 'http://gitorious.org/',
396 inputs => [ { label => 'Project:' }, { label => 'Repository:', suffix => '.git' } ]
400 # You can customize the gitweb interface widely by editing
401 # gitweb/gitweb_config.perl
404 ## Permission settings
406 # Girocco needs some way to manipulate write permissions to various parts of
407 # all repositories; this concerns three entities:
408 # - www-data: the web interface needs to be able to rewrite few files within
409 # the repository
410 # - repo: a user designated for cronjobs; handles mirroring and repacking;
411 # this one is optional if not $mirror
412 # - others: the designated users that are supposed to be able to push; they
413 # may have account either within chroot, or outside of it
415 # There are several ways how to use Girocco based on a combination of the
416 # following settings.
418 # (Non-chroot) UNIX user the CGI scripts run on; note that if some non-related
419 # untrusted CGI scripts run on this account too, that can be a big security
420 # problem and you'll probably need to set up suexec (poor you).
421 # This must always be set.
422 our $cgi_user = 'www-data';
424 # (Non-chroot) UNIX user performing mirroring jobs; this is the user who
425 # should run all the daemons and cronjobs and
426 # the user who should be running make install (if not root).
427 # This must always be set.
428 our $mirror_user = 'repo';
430 # (Non-chroot) UNIX group owning the repositories by default; it owns whole
431 # mirror repositories and at least web-writable metadata of push repositories.
432 # If you undefine this, all the data will become WORLD-WRITABLE.
433 # Both $cgi_user and $mirror_user should be members of this group!
434 our $owning_group = 'repo';
436 # Whether to use chroot jail for pushing; this must be always the same
437 # as $manage_users.
438 # TODO: Gitosis support for $manage_users and not $chrooted?
439 our $chrooted = $manage_users;
441 # How to control permissions of push-writable data in push repositories:
442 # * 'Group' for the traditional model: The $chroot/etc/group project database
443 # file is used as the UNIX group(5) file; the directories have gid appropriate
444 # for the particular repository and are group-writable. This works only if
445 # $chrooted so that users are put in the proper groups on login when using
446 # SSH push. Smart HTTPS push does not require a chroot to work -- simply
447 # run "make install" as the non-root $mirror_user user, but leave
448 # $manage_users and $chrooted enabled.
449 # * 'ACL' for a model based on POSIX ACL: The directories are coupled with ACLs
450 # listing the users with push permissions. This works for both chroot and
451 # non-chroot setups, however it requires ACL support within the filesystem.
452 # This option is BASICALLY UNTESTED, too. And UNIMPLEMENTED. :-)
453 # * 'Hooks' for a relaxed model: The directories are world-writable and push
454 # permission control is purely hook-driven. This is INSECURE and works only
455 # when you trust all your users; on the other hand, the attack vectors are
456 # mostly just DoS or fully-traceable tinkering.
457 our $permission_control = 'Group';
459 # Path to alternate screen multiuser acl file (see screen/README, undef for none)
460 our $screen_acl_file = undef;
463 ## sendmail.pl configuration
465 # Full information on available sendmail.pl settings can be found by running
466 # ../bin/sendmail.pl -v -h
468 # These settings will only used if $sendmail_bin is set to 'sendmail.pl'
470 # sendmail.pl host name
471 #$ENV{'SENDMAIL_PL_HOST'} = 'localhost'; # localhost is the default
473 # sendmail.pl port name
474 #$ENV{'SENDMAIL_PL_PORT'} = '25'; # port 25 is the default
476 # sendmail.pl nc executable
477 #$ENV{'SENDMAIL_PL_NCBIN'} = "$chroot/bin/nc.openbsd"; # default is nc found in $PATH
479 # sendmail.pl nc options
480 # multiple options may be included, e.g. '-4 -X connect -x 192.168.100.10:8080'
481 #$ENV{'SENDMAIL_PL_NCOPT'} = '-4'; # force IPv4, default is to allow IPv4 & IPv6
484 ## Sanity checks & defaults
486 # Couple of sanity checks and default settings (do not change these)
487 use Digest::MD5 qw(md5);
488 use MIME::Base64 qw(encode_base64);
489 $nickname = (split(/[.]/, $name))[0] unless $nickname;
490 our $tmpsuffix = substr(encode_base64(md5($name.':'.$nickname)),0,6);
491 $tmpsuffix =~ tr,+/,=_,;
492 ($mirror_user) or die "Girocco::Config: \$mirror_user must be set even if to current user";
493 ($basedir) or die "Girocco::Config: \$basedir must be set";
494 ($sendmail_bin) or die "Girocco::Config: \$sendmail_bin must be set";
495 $sendmail_bin = "$basedir/bin/sendmail.pl" if $sendmail_bin eq "sendmail.pl";
496 $screen_acl_file = "$basedir/screen/giroccoacl" unless $screen_acl_file;
497 $jailreporoot =~ s,^/+,,;
498 ($reporoot) or die "Girocco::Config \$reporoot must be set";
499 ($jailreporoot) or die "Girocco::Config \$jailreporoot must be set";
500 (not $mob or $mob eq 'mob') or die "Girocco::Config \$mob must be undef (or '') or 'mob'";
501 (not $min_key_length or $min_key_length =~ /^[1-9][0-9]*$/)
502 or die "Girocco::Config \$min_key_length must be undef or numeric";
503 $admincc = $admincc ? 1 : 0;
504 $rootcert = "$certsdir/girocco_root_crt.pem" if $httpspushurl && !$rootcert;
505 $clientcert = "$certsdir/girocco_client_crt.pem" if $httpspushurl && !$clientcert;
506 $clientkey = "$certsdir/girocco_client_key.pem" if $httpspushurl && !$clientkey;
507 $clientcertsuffix = "$certsdir/girocco_client_suffix.pem" if $httpspushurl && !$clientcertsuffix;
508 $mobusercert = "$certsdir/girocco_mob_user_crt.pem" if $httpspushurl && $mob && !$mobusercert;
509 $mobuserkey = "$certsdir/girocco_mob_user_key.pem" if $httpspushurl && $mob && !$mobuserkey;
510 our $mobpushurl = $pushurl;
511 $mobpushurl =~ s,^ssh://,ssh://mob@,i if $mobpushurl;
512 $disable_dsa = 1 unless $pushurl;
513 $disable_dsa = $disable_dsa ? 1 : '';
514 our $httpdnsname = ($gitweburl =~ m,https?://([A-Za-z0-9.-]+),i) ? lc($1) : undef if $gitweburl;
515 our $httpsdnsname = ($httpspushurl =~ m,https://([A-Za-z0-9.-]+),i) ? lc($1) : undef if $httpspushurl;
516 ($mirror or $push) or die "Girocco::Config: neither \$mirror nor \$push is set?!";
517 (not $push or ($pushurl or $httpspushurl or $gitpullurl or $httppullurl)) or die "Girocco::Config: no pull URL is set";
518 (not $push or ($pushurl or $httpspushurl)) or die "Girocco::Config: \$push set but \$pushurl and \$httpspushurl are undef";
519 (not $mirror or $mirror_user) or die "Girocco::Config: \$mirror set but \$mirror_user is undef";
520 ($manage_users == $chrooted) or die "Girocco::Config: \$manage_users and \$chrooted must be set to the same value";
521 (not $chrooted or $permission_control ne 'ACL') or die "Girocco::Config: resolving uids for ACL not supported when using chroot";
522 (grep { $permission_control eq $_ } qw(Group Hooks)) or die "Girocco::Config: \$permission_control must be set to Group or Hooks";
523 ($chrooted or not $mob) or die "Girocco::Config: mob user supported only in the chrooted mode";
524 (not $httpspushurl or $httpsdnsname) or die "Girocco::Config invalid \$httpspushurl does not start with https://domainname";