Girocco/Validator.pm: sanctify non-default Config.pm
[girocco/readme.git] / Girocco / Validator.pm
blob78876aa89346de089b49236d8d68de47cd682e5e
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;
12 BEGIN {
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;
20 use strict;
21 use warnings;
22 no strict 'vars'; # required since Config.pm declares the variables
24 BEGIN {
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)
38 require Digest::MD5;
39 require MIME::Base64;
40 defined($name) or $name = "";
41 $name =~ s/\s+/_/gs;
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 $admincc = $admincc ? 1 : 0;
77 $rootcert = "$certsdir/girocco_root_crt.pem" if $httpspushurl && !$rootcert;
78 $clientcert = "$certsdir/girocco_client_crt.pem" if $httpspushurl && !$clientcert;
79 $clientkey = "$certsdir/girocco_client_key.pem" if $httpspushurl && !$clientkey;
80 $clientcertsuffix = "$certsdir/girocco_client_suffix.pem" if $httpspushurl && !$clientcertsuffix;
81 $mobusercert = "$certsdir/girocco_mob_user_crt.pem" if $httpspushurl && $mob && !$mobusercert;
82 $mobuserkey = "$certsdir/girocco_mob_user_key.pem" if $httpspushurl && $mob && !$mobuserkey;
83 our $mobpushurl = $pushurl;
84 $mobpushurl =~ s,^ssh://,ssh://mob@,i if $mobpushurl;
85 $disable_dsa = 1 unless $pushurl;
86 $disable_dsa = $disable_dsa ? 1 : '';
87 our $httpdnsname = ($gitweburl =~ m,https?://([A-Za-z0-9.-]+),i) ? lc($1) : undef if $gitweburl;
88 our $httpsdnsname = ($httpspushurl =~ m,https://([A-Za-z0-9.-]+),i) ? lc($1) : undef if $httpspushurl;
89 $SmartHTTPOnly = $SmartHTTPOnly ? 1 : '';
90 $TLSHost = $TLSHost ? 1 : '';
91 $pretrustedroot = $pretrustedroot ? 1 : '';
92 $suppress_git_ssh_logging = $suppress_git_ssh_logging ? 1 : '';
93 $git_daemon_any_host = $git_daemon_any_host ? 1 : '';
94 if ((!defined($git_daemon_host_list) || $git_daemon_host_list =~ /^\s*$/) &&
95 (defined($gitpullurl) && $gitpullurl =~ m{^git://\[?[A-Za-z0-9.-:]}i)) {
96 if ($gitpullurl =~ m{^[gG][iI][tT]://([A-Za-z0-9.-]+)(?:[/:]|$)} ||
97 $gitpullurl =~ m{^[gG][iI][tT]://\[([0-9a-zA-Z.:%]+)\](?:[/:]|$)}) {
98 my $gdhn = lc($1);
99 $gdhn ne "." and $gdhn =~ s/\.$//;
100 my $gdhnl = $gdhn; $gdhnl =~ s/(?<!^)(?<!\.)\..*$//;
101 $git_daemon_host_list="$gdhn";
102 do {$git_daemon_host_list.=" $_" unless index(" $git_daemon_host_list "," $_ ")>=0}
103 foreach $gdhnl, qw"localhost ::1 127.0.0.1";
106 if (defined($git_daemon_host_list)) {
107 $git_daemon_host_list = lc($git_daemon_host_list);
108 $git_daemon_host_list =~ s/^\s+//;
109 $git_daemon_host_list =~ s/\s+$//;
110 $git_daemon_host_list = undef if $git_daemon_host_list eq "";
112 $mirror || $push or
113 die "Girocco::Config: neither \$mirror nor \$push is set?!";
114 !$push || ($pushurl || $httpspushurl || $gitpullurl || $httppullurl) or
115 die "Girocco::Config: no pull URL is set";
116 !$push || ($pushurl || $httpspushurl) or
117 die "Girocco::Config: \$push set but \$pushurl and \$httpspushurl are undef";
118 !$mirror || $mirror_user or
119 die "Girocco::Config: \$mirror set but \$mirror_user is undef";
120 $TLSHost = $TLSHost ? 1 : '';
121 $manage_users = $manage_users ? 1 : 0;
122 $chrooted = $chrooted ? 1 : 0;
123 $manage_users == $chrooted or
124 die "Girocco::Config: \$manage_users and \$chrooted must be set to the same value";
125 !$chrooted || uc($permission_control) ne 'ACL' or
126 die "Girocco::Config: resolving uids for ACL not supported when using chroot";
127 defined($permission_control) or $permission_control = '';
128 $permission_control = ucfirst(lc($permission_control));
129 (grep { $permission_control eq $_ } qw(Group Hooks)) or
130 die "Girocco::Config: \$permission_control must be set to Group or Hooks";
131 $chrooted || !$mob or
132 die "Girocco::Config: mob user supported only in the chrooted mode";
133 !$httpspushurl || $httpsdnsname or
134 die "Girocco::Config: \$httpspushurl invalid does not start with https://domainname";
135 !$svn_log_window_size || $svn_log_window_size =~ /^[1-9][0-9]*$/ or
136 die "Girocco::Config: \$svn_log_window_size must be undef or numeric";
137 defined($max_file_size512) && !$max_file_size512 and $max_file_size512 = undef;
138 !defined($max_file_size512) || $max_file_size512 =~ /^[1-9][0-9]*$/ && $max_file_size512 <= 2147483647 or
139 die "Girocco::Config: \$max_file_size512 must be undef or a positive integer <= 2147483647";
140 defined($max_clone_objects) && !$max_clone_objects and $max_clone_objects = undef;
141 !defined($max_clone_objects) || $max_clone_objects =~ /^[1-9][0-9]*$/ or
142 die "Girocco::Config: \$max_clone_objects must be undef or a positive integer";
143 !defined($posix_sh_bin) || $posix_sh_bin !~ /\s/ or
144 die "Girocco::Config: \$posix_sh_bin must not contain any whitespace";
145 !defined($perl_bin) || $perl_bin !~ /\s/ or
146 die "Girocco::Config: \$perl_bin must not contain any whitespace";
147 !$delay_gfi_redelta and $delay_gfi_redelta = undef;
148 !$git_no_mmap and $git_no_mmap = undef;
149 !$suppress_x_girocco and $suppress_x_girocco = undef;
150 !$jgit_compatible_bitmaps and $jgit_compatible_bitmaps = undef;
151 !$autogchack and $autogchack = undef;
152 !$reflogs_lifetime || $reflogs_lifetime !~ /^[1-9][0-9]*$/ and $reflogs_lifetime = 1;
153 $reflogs_lifetime = 0 + $reflogs_lifetime;
154 $reflogs_lifetime >= 0 or $reflogs_lifetime = 1;
155 $reflogs_lifetime <= 30 or $reflogs_lifetime = 30;
156 !defined $upload_pack_window || $upload_pack_window =~ /^[1-9][0-9]*$/ or
157 die "Girocco::Config: \$upload_pack_window must be undef or numeric";
158 !defined $upload_pack_window || (2 <= $upload_pack_window && $upload_pack_window <= 50) or
159 die "Girocco::Config: \$upload_pack_window must be in range 2..50";
160 !defined $max_receive_size || $max_receive_size =~ /^\d+[kKmMgG]?$/ or
161 die "Girocco::Config: \$max_receive_size setting is invalid";
162 defined($ENV{'SENDMAIL_PL_HOST'}) and eval 'our $sendmail_pl_host = $ENV{"SENDMAIL_PL_HOST"}';
163 defined($ENV{'SENDMAIL_PL_PORT'}) and eval 'our $sendmail_pl_port = $ENV{"SENDMAIL_PL_PORT"}';
164 defined($ENV{'SENDMAIL_PL_NCBIN'}) and eval 'our $sendmail_pl_ncbin = $ENV{"SENDMAIL_PL_NCBIN"}';
165 defined($ENV{'SENDMAIL_PL_NCOPT'}) and eval 'our $sendmail_pl_ncopt = $ENV{"SENDMAIL_PL_NCOPT"}';
166 defined($ENV{'PYTHON'}) and eval 'our $python = $ENV{"PYTHON"}';
168 # jailreporoot MUST NOT be absolute
169 defined($jailreporoot) && substr($jailreporoot, 0, 1) ne "/" or
170 die "Girocco::Config: \$jailreporoot MUST NOT be an absolute path\n";
172 # webreporoot can be undef
173 !defined($webreporoot) || substr($webreporoot, 0, 1) eq "/" or
174 die "Girocco::Config: \$webreporoot MUST be an absolute path if not undef\n";
176 # All these MUST be absolute paths
178 no strict 'refs';
179 defined(${$_}) && substr(${$_}, 0, 1) eq "/" or
180 die "Girocco::Config: \$$_ MUST be an absolute path\n"
181 foreach qw(basedir certsdir reporoot chroot webroot cgiroot projlist_cache_dir);
184 # Make sure Git has a consistent and reproducible environment
186 $ENV{'XDG_CONFIG_HOME'} = $chroot.'/var/empty';
187 $ENV{'HOME'} = $chroot.'/etc/girocco';
188 $ENV{'TMPDIR'} = '/tmp';
189 $ENV{'GIT_CONFIG_NOSYSTEM'} = 1;
190 $ENV{'GIT_ATTR_NOSYSTEM'} = 1;
191 $ENV{'GIT_NO_REPLACE_OBJECTS'} = 1;
192 $ENV{'GIT_TERMINAL_PROMPT'} = 0;
193 $ENV{'GIT_ASKPASS'} = $basedir.'/bin/git-askpass-password';
194 delete $ENV{'GIT_USER_AGENT'};
195 $ENV{'GIT_USER_AGENT'} = $git_client_ua if defined($git_client_ua);
196 delete $ENV{'GIT_HTTP_USER_AGENT'};
197 delete $ENV{'GIT_CONFIG_PARAMETERS'};
198 delete $ENV{'GIT_ALTERNATE_OBJECT_DIRECTORIES'};
199 delete $ENV{'GIT_CONFIG'};
200 delete $ENV{'GIT_DIR'};
201 delete $ENV{'GIT_GRAFT_FILE'};
202 delete $ENV{'GIT_INDEX_FILE'};
203 delete $ENV{'GIT_OBJECT_DIRECTORY'};
204 delete $ENV{'GIT_NAMESPACE'};
206 # Guarantee a sane umask for Girocco
208 umask(umask() & ~0770);