1 # This install-only package contains validation, sanity and default
2 # checks for the values set in Girocco::Config.
4 # It's only used during the install process.
5 # Normally the Girocco::Config file will "require" this module
6 # at the end (before it's frozen during installation).
7 # However, the install process specifically "use"s this module to
8 # guarantee the checks always run even if that "require" is removed.
10 package Girocco
::Validator
;
13 # This check MUST NOT be inside the Girocco::Config package
14 scalar(eval 'keys %Girocco::Config::') or
15 die "Girocco::Config must already be 'use'd before ".__PACKAGE__
." is 'use'd.\n";
18 package Girocco
::Config
;
22 no strict
'vars'; # required since Config.pm declares the variables
25 # Makes non-Config modules work with non-default Config
26 exists($INC{'Girocco/Config.pm'}) or
27 $INC{'Girocco/Config.pm'} = $INC{'Girocco/Validator.pm'};
31 ## ------------------------
32 ## Sanity checks & defaults
33 ## ------------------------
35 # Changing anything in this section can result in unexpected breakage
37 # Couple of sanity checks and default settings (do not change these)
40 defined($name) or $name = "";
42 $nickname = lc((split(/[.]/, $name))[0]) unless defined($nickname) && $nickname ne "";
43 $nickname =~ s/\s+/_/gs;
44 our $tmpsuffix = substr(MIME
::Base64
::encode_base64
(Digest
::MD5
::md5
($name.':'.$nickname)),0,6);
45 $tmpsuffix =~ tr
,+/,=_
,;
46 defined($mirror_user) && $mirror_user ne "" or
47 die "Girocco::Config: \$mirror_user must be set even if to current user";
48 defined($basedir) && $basedir ne "" or
49 die "Girocco::Config: \$basedir must be set";
50 defined($sendmail_bin) && $sendmail_bin ne "" or
51 die "Girocco::Config: \$sendmail_bin must be set";
52 $sendmail_bin eq "sendmail.pl" and $sendmail_bin = "$basedir/bin/sendmail.pl";
53 defined($screen_acl_file) && $screen_acl_file ne "" or
54 $screen_acl_file = "$basedir/screen/giroccoacl";
55 defined($jailreporoot) or $jailreporoot = "";
56 $jailreporoot =~ s
,^/+,,;
57 $reporoot ne "" or die "Girocco::Config: \$reporoot must be set";
58 $jailreporoot ne "" or die "Girocco::Config: \$jailreporoot must be set";
59 $disable_jailsetup = $disable_jailsetup ?
1 : '';
60 $notify_single_level = $notify_single_level ?
1 : '';
61 $fetch_stash_refs = $fetch_stash_refs ?
1 : '';
62 !$mob || $mob eq 'mob' or die "Girocco::Config: \$mob must be undef (or '') or 'mob'";
63 !defined($protect_fields) || ref($protect_fields) eq 'HASH' or
64 die "Girocco::Config: \$protect_fields must be a HASH ref or undefined";
65 ref($protect_fields) eq 'HASH' or $protect_fields = {};
66 $project_edit_timeout =~ /^[1-9][0-9]*$/ or
67 die "Girocco::Config: \$project_edit_timeout must be a positive integer";
68 5 <= $project_edit_timeout && $project_edit_timeout <= 86400 or
69 die "Girocco::Config: \$project_edit_timeout seems unreasonable: $project_edit_timeout";
70 !$min_key_length || $min_key_length =~ /^[1-9][0-9]*$/ or
71 die "Girocco::Config: \$min_key_length must be undef or numeric";
72 !defined($max_readme_size) || $max_readme_size =~ /^[0-9]+$/ or
73 die "Girocco::Config: \$max_readme_size must be a whole number";
74 defined($mailsh_sizelimit) && $mailsh_sizelimit =~ /^[1-9][0-9]*$/ or
75 die "Girocco::Config: \$mailsh_sizelimit must be a positive number";
76 !defined($initial_branch) || $initial_branch eq "" ||
77 $initial_branch !~ /^\/|^\
.|[\x00-\x1f \x7f\
[\
[~^"'"<>*?
\\:]|\@\
{|\
.\
.|\
.lock$|\
.$|\
/$/ or
78 die "Girocco::Config: \$initial_branch grossly invalid: $initial_branch";
79 if (defined($empty_commit_message)) {
80 $empty_commit_message =~ s/^\s+//;
81 $empty_commit_message =~ s/\s+$//;
83 $admincc = $admincc ?
1 : 0;
84 $rootcert = "$certsdir/girocco_root_crt.pem" if $httpspushurl && !$rootcert;
85 $clientcert = "$certsdir/girocco_client_crt.pem" if $httpspushurl && !$clientcert;
86 $clientkey = "$certsdir/girocco_client_key.pem" if $httpspushurl && !$clientkey;
87 $clientcertsuffix = "$certsdir/girocco_client_suffix.pem" if $httpspushurl && !$clientcertsuffix;
88 $mobusercert = "$certsdir/girocco_mob_user_crt.pem" if $httpspushurl && $mob && !$mobusercert;
89 $mobuserkey = "$certsdir/girocco_mob_user_key.pem" if $httpspushurl && $mob && !$mobuserkey;
90 our $mobpushurl = $pushurl;
91 $mobpushurl =~ s
,^ssh
://,ssh
://mob@
,i
if $mobpushurl;
92 $disable_dsa = 1 unless $pushurl;
93 $disable_dsa = $disable_dsa ?
1 : '';
94 our $httpdnsname = ($gitweburl =~ m
,https?
://([A
-Za
-z0
-9.-]+),i
) ?
lc($1) : undef if $gitweburl;
95 our $httpsdnsname = ($httpspushurl =~ m
,https
://([A
-Za
-z0
-9.-]+),i
) ?
lc($1) : undef if $httpspushurl;
96 $SmartHTTPOnly = $SmartHTTPOnly ?
1 : '';
97 $TLSHost = $TLSHost ?
1 : '';
98 $pretrustedroot = $pretrustedroot ?
1 : '';
99 $suppress_git_ssh_logging = $suppress_git_ssh_logging ?
1 : '';
100 $git_daemon_any_host = $git_daemon_any_host ?
1 : '';
101 if ((!defined($git_daemon_host_list) || $git_daemon_host_list =~ /^\s*$/) &&
102 (defined($gitpullurl) && $gitpullurl =~ m{^git://\[?[A-Za-z0-9.-:]}i)) {
103 if ($gitpullurl =~ m{^[gG][iI][tT]://([A-Za-z0-9.-]+)(?:[/:]|$)} ||
104 $gitpullurl =~ m{^[gG][iI][tT]://\[([0-9a-zA-Z.:%]+)\](?:[/:]|$)}) {
106 $gdhn ne "." and $gdhn =~ s/\.$//;
107 my $gdhnl = $gdhn; $gdhnl =~ s/(?<!^)(?<!\.)\..*$//;
108 $git_daemon_host_list="$gdhn";
109 do {$git_daemon_host_list.=" $_" unless index(" $git_daemon_host_list "," $_ ")>=0}
110 foreach $gdhnl, qw
"localhost ::1 127.0.0.1";
113 if (defined($git_daemon_host_list)) {
114 $git_daemon_host_list = lc($git_daemon_host_list);
115 $git_daemon_host_list =~ s/^\s+//;
116 $git_daemon_host_list =~ s/\s+$//;
117 $git_daemon_host_list = undef if $git_daemon_host_list eq "";
120 die "Girocco::Config: neither \$mirror nor \$push is set?!";
121 !$push || ($pushurl || $httpspushurl || $gitpullurl || $httppullurl) or
122 die "Girocco::Config: no pull URL is set";
123 !$push || ($pushurl || $httpspushurl) or
124 die "Girocco::Config: \$push set but \$pushurl and \$httpspushurl are undef";
125 !$mirror || $mirror_user or
126 die "Girocco::Config: \$mirror set but \$mirror_user is undef";
127 $TLSHost = $TLSHost ?
1 : '';
128 $manage_users = $manage_users ?
1 : 0;
129 $chrooted = $chrooted ?
1 : 0;
130 $manage_users == $chrooted or
131 die "Girocco::Config: \$manage_users and \$chrooted must be set to the same value";
132 !$chrooted || uc($permission_control) ne 'ACL' or
133 die "Girocco::Config: resolving uids for ACL not supported when using chroot";
134 defined($permission_control) or $permission_control = '';
135 $permission_control = ucfirst(lc($permission_control));
136 (grep { $permission_control eq $_ } qw(Group Hooks)) or
137 die "Girocco::Config: \$permission_control must be set to Group or Hooks";
138 $chrooted || !$mob or
139 die "Girocco::Config: mob user supported only in the chrooted mode";
140 !$httpspushurl || $httpsdnsname or
141 die "Girocco::Config: \$httpspushurl invalid does not start with https://domainname";
142 !$svn_log_window_size || $svn_log_window_size =~ /^[1-9][0-9]*$/ or
143 die "Girocco::Config: \$svn_log_window_size must be undef or numeric";
144 defined($max_file_size512) && !$max_file_size512 and $max_file_size512 = undef;
145 !defined($max_file_size512) || $max_file_size512 =~ /^[1-9][0-9]*$/ && $max_file_size512 <= 2147483647 or
146 die "Girocco::Config: \$max_file_size512 must be undef or a positive integer <= 2147483647";
147 defined($max_clone_objects) && !$max_clone_objects and $max_clone_objects = undef;
148 !defined($max_clone_objects) || $max_clone_objects =~ /^[1-9][0-9]*$/ or
149 die "Girocco::Config: \$max_clone_objects must be undef or a positive integer";
150 !defined($posix_sh_bin) || $posix_sh_bin !~ /\s/ or
151 die "Girocco::Config: \$posix_sh_bin must not contain any whitespace";
152 !defined($perl_bin) || $perl_bin !~ /\s/ or
153 die "Girocco::Config: \$perl_bin must not contain any whitespace";
154 !$delay_gfi_redelta and $delay_gfi_redelta = undef;
155 !$git_no_mmap and $git_no_mmap = undef;
156 !$suppress_x_girocco and $suppress_x_girocco = undef;
157 !$jgit_compatible_bitmaps and $jgit_compatible_bitmaps = undef;
158 !$autogchack and $autogchack = undef;
159 !$reflogs_lifetime || $reflogs_lifetime !~ /^[1-9][0-9]*$/ and $reflogs_lifetime = 1;
160 $reflogs_lifetime = 0 + $reflogs_lifetime;
161 $reflogs_lifetime >= 0 or $reflogs_lifetime = 1;
162 $reflogs_lifetime <= 30 or $reflogs_lifetime = 30;
163 !defined $upload_pack_window || $upload_pack_window =~ /^[1-9][0-9]*$/ or
164 die "Girocco::Config: \$upload_pack_window must be undef or numeric";
165 !defined $upload_pack_window || (2 <= $upload_pack_window && $upload_pack_window <= 50) or
166 die "Girocco::Config: \$upload_pack_window must be in range 2..50";
167 !defined $max_receive_size || $max_receive_size =~ /^\d+[kKmMgG]?$/ or
168 die "Girocco::Config: \$max_receive_size setting is invalid";
169 defined $git_shared_repository_setting or $git_shared_repository_setting = 2;
170 $git_shared_repository_setting = lc($git_shared_repository_setting);
172 $git_shared_repository_setting =~ /^(?:false|umask|00*)$/ and do {
173 $git_shared_repository_setting = 0;
175 $var_umask_ug = $var_umask;
178 $git_shared_repository_setting =~ /^(?:true|group|1|00*1)$/ and do {
179 $git_shared_repository_setting = 1;
181 $var_umask_ug = $var_umask;
184 $git_shared_repository_setting =~ /^(?:all|world|everybody|2|00*2)$/ and do {
185 $git_shared_repository_setting = 2;
187 $var_umask_ug = '0117';
190 $git_shared_repository_setting =~ /^0[0-7]{1,3}$/ and do {
191 my $p = oct($git_shared_repository_setting);
194 $git_shared_repository_setting = sprintf("0%03o", $p);
195 $var_umask = sprintf("0%03o", $p ^ 0777);
196 $var_umask_ug = sprintf("0%03o", ($p ^ 0777) | 007);
199 die "Invalid \$Girocco::Config::git_shared_repository_setting setting ($git_shared_repository_setting)\n";
201 $var_umask_perm = $permission_control eq 'Group' ?
$var_umask : '0';
202 defined($ENV{'SENDMAIL_PL_HOST'}) and eval 'our $sendmail_pl_host = $ENV{"SENDMAIL_PL_HOST"}';
203 defined($ENV{'SENDMAIL_PL_PORT'}) and eval 'our $sendmail_pl_port = $ENV{"SENDMAIL_PL_PORT"}';
204 defined($ENV{'SENDMAIL_PL_NCBIN'}) and eval 'our $sendmail_pl_ncbin = $ENV{"SENDMAIL_PL_NCBIN"}';
205 defined($ENV{'SENDMAIL_PL_NCOPT'}) and eval 'our $sendmail_pl_ncopt = $ENV{"SENDMAIL_PL_NCOPT"}';
206 defined($ENV{'PYTHON'}) and eval 'our $python = $ENV{"PYTHON"}';
208 # jailreporoot MUST NOT be absolute
209 defined($jailreporoot) && substr($jailreporoot, 0, 1) ne "/" or
210 die "Girocco::Config: \$jailreporoot MUST NOT be an absolute path\n";
212 # webreporoot can be undef
213 !defined($webreporoot) || substr($webreporoot, 0, 1) eq "/" or
214 die "Girocco::Config: \$webreporoot MUST be an absolute path if not undef\n";
216 # All these MUST be absolute paths
219 defined(${$_}) && substr(${$_}, 0, 1) eq "/" or
220 die "Girocco::Config: \$$_ MUST be an absolute path\n"
221 foreach qw(basedir certsdir reporoot chroot webroot cgiroot projlist_cache_dir);
224 # Make sure Git has a consistent and reproducible environment
226 $ENV{'XDG_CONFIG_HOME'} = $chroot.'/var/empty';
227 $ENV{'HOME'} = $chroot.'/etc/girocco';
228 $ENV{'TMPDIR'} = '/tmp';
229 $ENV{'GIT_CONFIG_NOSYSTEM'} = 1;
230 $ENV{'GIT_ATTR_NOSYSTEM'} = 1;
231 $ENV{'GIT_NO_REPLACE_OBJECTS'} = 1;
232 $ENV{'GIT_TERMINAL_PROMPT'} = 0;
233 $ENV{'GIT_ASKPASS'} = $basedir.'/bin/git-askpass-password';
234 delete $ENV{'GIT_USER_AGENT'};
235 $ENV{'GIT_USER_AGENT'} = $git_client_ua if defined($git_client_ua);
236 delete $ENV{'GIT_HTTP_USER_AGENT'};
237 delete $ENV{'GIT_CONFIG_PARAMETERS'};
238 delete $ENV{'GIT_ALTERNATE_OBJECT_DIRECTORIES'};
239 delete $ENV{'GIT_CONFIG'};
240 delete $ENV{'GIT_DIR'};
241 delete $ENV{'GIT_GRAFT_FILE'};
242 delete $ENV{'GIT_INDEX_FILE'};
243 delete $ENV{'GIT_OBJECT_DIRECTORY'};
244 delete $ENV{'GIT_NAMESPACE'};
246 # Guarantee a sane umask for Girocco
248 umask(umask() & ~0770);