11 use Digest
::SHA1
qw(sha1_hex);
16 filedb_atomic_append
(jailed_file
('/etc/passwd'),
17 join(':', $self->{name
}, 'x', '\i', 65534, $self->{email
}, '/', '/bin/git-shell'));
22 '/etc/sshkeys/'.$self->{name
};
27 open F
, "<".jailed_file
($self->_sshkey_path) or die "sshkey load failed: $!";
32 if (/^ssh-(?:dss|rsa) /) {
34 } elsif (/^# REPOAUTH ([0-9a-f]+) (\d+)/) {
36 $auth = $1 unless (time >= $expire);
40 my $keys = join('', @keys); chomp $keys;
46 open F
, ">".jailed_file
($self->_sshkey_path) or die "sshkey failed: $!";
47 if (defined($self->{auth
}) && $self->{auth
}) {
48 my $expire = time + 24 * 3600;
49 print F
"# REPOAUTH $self->{auth} $expire\n";
51 print F
$self->{keys}."\n";
53 chmod 0664, jailed_file
($self->_sshkey_path);
56 # private constructor, do not use
60 Girocco
::User
::valid_name
($name) or die "refusing to create user with invalid name ($name)!";
61 my $proj = { name
=> $name };
66 # public constructor #0
67 # creates a virtual user not connected to disk record
68 # you can conjure() it later to disk
72 my $self = $class->_new($name);
76 # public constructor #1
81 open F
, jailed_file
("/etc/passwd") or die "user load failed: $!";
85 next unless (shift eq $name);
87 my $self = $class->_new($name);
89 (undef, $self->{uid
}, undef, $self->{email
}) = @_;
90 ($self->{keys}, $self->{auth
}) = $self->_sshkey_load;
98 # public constructor #2
103 open F
, jailed_file
("/etc/passwd") or die "user load failed: $!";
107 next unless ($_[2] eq $uid);
109 my $self = $class->_new($_[0]);
111 (undef, undef, $self->{uid
}, undef, $self->{email
}) = @_;
112 ($self->{keys}, $self->{auth
}) = $self->_sshkey_load;
120 # $user may not be in sane state if this returns false!
124 my $cgi = $gcgi->cgi;
126 $self->{name
} = $gcgi->wparam('name');
127 Girocco
::User
::valid_name
($self->{name
})
128 or $gcgi->err("Name contains invalid characters.");
130 $self->{email
} = $gcgi->wparam('email');
131 valid_email
($self->{email
})
132 or $gcgi->err("Your email sure looks weird...?");
134 $self->keys_fill($gcgi);
140 my $cgi = $gcgi->cgi;
142 $self->{keys} = $cgi->param('keys');
143 length($self->{keys}) <= 4096
144 or $gcgi->err("The list of keys is more than 4kb. Do you really need that much?");
145 foreach (split /\r?\n/, $self->{keys}) {
146 /^ssh-(?:dss|rsa) .* \S+@\S+$/ or $gcgi->err("Your ssh key (\"$_\") appears to have invalid format (does not start by ssh-dss|rsa or does not end with @-identifier) - maybe your browser has split a single key to multiple lines?");
149 not $gcgi->err_check;
161 $self->{auth
} = Digest
::SHA1
::sha1_hex
(time . $$ . rand() . $self->{keys});
169 delete $self->{auth
};
183 /^[a-zA-Z0-9+._-]+$/;
188 Girocco
::User
::valid_name
($name) or die "tried to query for user with invalid name $name!";
189 (-e jailed_file
("/etc/sshkeys/$name"));
194 $Girocco::Config
::chrooted
and undef; # TODO for ACLs within chroot
195 scalar(getpwnam($name));