view release on metacpan or search on metacpan
site/templates/bootstrap/customLoginFooter.tpl
site/templates/bootstrap/customLoginHeader.tpl
site/templates/bootstrap/decryptvalue.tpl
site/templates/bootstrap/error.tpl
site/templates/bootstrap/errormsg.tpl
site/templates/bootstrap/ext2fcheck.tpl
site/templates/bootstrap/finduser.tpl
site/templates/bootstrap/footer.tpl
site/templates/bootstrap/generic2fregister.tpl
site/templates/bootstrap/globallogout.tpl
site/templates/bootstrap/gpgform.tpl
site/templates/bootstrap/header.tpl
site/templates/bootstrap/idpchoice.tpl
site/templates/bootstrap/impersonation.tpl
site/templates/bootstrap/info.tpl
site/templates/bootstrap/ldapPpGrace.tpl
site/templates/bootstrap/login.tpl
site/templates/bootstrap/mail.tpl
site/templates/bootstrap/menu.tpl
site/templates/bootstrap/noHistory.tpl
site/templates/bootstrap/notification.tpl
t/crowdsec-scenarii/http-cve-test/patterns.re
t/crowdsec-scenarii/http-sensitive-files/.scenario
t/crowdsec-scenarii/http-sensitive-files/patterns.txt
t/crowdsec-scenarii/legacy.url.re
t/crowdsec-scenarii/urlskip/allowed.txt
t/Custom.pm
t/CustomMenu.pm
t/DbiCustomHash.pm
t/geoip/GeoIP2-City-Test.mmdb
t/geoip/GeoIP2-Country-Test.mmdb
t/gpghome/key.asc
t/gpghome/openpgp-revocs.d/9482CEFB055809CBAFE6D71AAB2D5542891D1677.rev
t/gpghome/private-keys-v1.d/A076B0E7DB141A919271EE8B581CDFA8DA42F333.key
t/gpghome/private-keys-v1.d/B7219440BCCD85200121CFB89F94C8D98C0397B3.key
t/gpghome/pubring.kbx
t/gpghome/tofu.db
t/gpghome/trustdb.gpg
t/HistoryPlugin.pm
t/lib/Apache/Session/Timeout.pm
t/lib/Lemonldap/NG/Common/Conf/Backends/Timeout.pm
t/lib/Lemonldap/NG/Handler/Test.pm
t/lib/Lemonldap/NG/Portal/Auth/LDAPPolicy.pm
t/lib/Lemonldap/NG/Portal/Custom.pm
t/lmConf-1.json
t/LogoutFail.pm
t/main-idps-renater-metadata.xml
t/main-sps-renater-metadata.xml
lib/Lemonldap/NG/Portal/Auth/GPG.pm view on Meta::CPAN
has tmp => (
is => 'rw',
default => sub {
tempdir( CLEANUP => 1 );
},
);
sub init {
my $self = shift;
$self->db( $self->conf->{gpgDb} );
unless ( $self->db ) {
$self->error("gpgDb not set");
return 0;
}
unless ( -r $self->db ) {
$self->error( "Unable to read " . $self->db );
return 0;
}
return $self->SUPER::init();
}
sub extractFormInfo {
my ( $self, $req ) = @_;
unless ( $self->ottRule->( $req, {} ) ) {
$self->error("OTT isn't set, unable to use GPG");
}
# Keep token data for later use
my ( $token, $gpgToken );
if ( $token = $req->param('token') ) {
$gpgToken = $self->ott->getToken($token);
$req->data->{tokenVerified} = 1 if ($gpgToken);
}
my $res = $self->SUPER::extractFormInfo($req);
return $res if ($res);
my $signed = $req->data->{password};
unless ( $signed =~ /SIGNATURE/s ) {
$self->userLogger->error("Bad signature content");
$self->userLogger->debug($signed);
$self->setSecurity($req);
return PE_BADCREDENTIALS;
}
unless ( $signed =~ /\b\Q$token\E\b/ ) {
$self->userLogger->error("User replayed a bad token in GPG !");
$self->setSecurity($req);
return PE_BADCREDENTIALS;
}
my ( $out, $err );
$self->logger->debug(
"Launching:\ngpgv --homedir /dev/null --keyring $self->{db} <<EOF\n$signed\nEOF"
);
my ( $lang, $language ) = ( $ENV{LANG}, $ENV{LANGUAGE} );
$ENV{LANG} = $ENV{LANGUAGE} = 'C';
IPC::Run::run( [ 'gpgv', '--homedir', '/dev/null', '--keyring', $self->db ],
\$signed, \$out, \$err, IPC::Run::timeout(10) );
if ( $? >> 8 != 0 ) {
$self->userLogger->error("GPG verification fails:\n$out\n# # #\n$err");
$self->setSecurity($req);
return PE_BADCREDENTIALS;
}
$self->setSecurity($req);
$self->userLogger->notice("Good GPG signature");
$self->userLogger->debug("GPG out:\n$out\n$err");
my $key;
if ( $err =~ /using .*? key (.*)$/m ) {
$key = $1;
chomp $key;
}
else {
$self->logger->error("Unable to parse gpgv result:\n$err");
return PE_ERROR;
}
$self->logger->debug("GPG full sign key: $key");
my $in;
IPC::Run::run( [
'gpg', '--homedir', $self->tmp, '--keyring',
$self->db, '--list-key', $key
],
\$in,
\$out,
\$err,
IPC::Run::timeout(10)
);
( $ENV{LANG}, $ENV{LANGUAGE} ) = ( $lang, $language );
if ( $? >> 8 != 0 ) {
$self->logger->error("gpg --list-key return an error:\n$err");
return PE_ERROR;
}
if ( $out =~ /pub [^\n]*\r?\n +([^\n]+)\n/ ) {
$key = $1;
chomp $key;
}
else {
$self->logger->error(
"Unable to parse gpg --list-key result:\n$out\n$err\n");
return PE_ERROR;
}
$self->logger->debug("GPG full master key: $key");
# Keep only gpgKeyLength characters
my $length = $self->conf->{gpgKeyLength} || 8;
$length = 8 if ( $length < 8 );
$key =~ s/.*?(.{8,$length})$/$1/;
$self->logger->info("User key: $key");
my @identities = ( $out =~ /uid\s+(.*)$/gm );
my $mail = $req->param('user');
foreach (@identities) {
if (/^(.*)\s+<\Q$mail\E>/) {
$req->data->{gpgFullName} = $1;
$req->data->{gpgMail} = $mail;
$req->user($mail);
$self->userLogger->notice("GPG user $mail authenticated");
return PE_OK;
}
}
$self->userLogger->warn("Given mail does not match with gpg key");
$self->setSecurity($req);
return PE_BADCREDENTIALS;
}
sub authenticate {
return PE_OK;
}
sub setAuthSessionInfo {
my ( $self, $req ) = @_;
$req->sessionInfo->{gpgMail} = $req->data->{gpgMail};
$req->sessionInfo->{authenticationLevel} = $self->conf->{gpgAuthnLevel};
return PE_OK;
}
sub authLogout {
return PE_OK;
}
sub getDisplayType {
return "gpgform";
}
1;
lib/Lemonldap/NG/Portal/Auth/GitHub.pm view on Meta::CPAN
$_[0]->conf->{githubPublicKeysEndpoint}
|| 'https://api.github.com/user/keys';
}
);
has githubGPGKeysEndpoint => (
is => 'ro',
lazy => 1,
default => sub {
$_[0]->conf->{githubGPGKeysEndpoint}
|| 'https://api.github.com/user/gpg_keys';
}
);
sub init {
my ($self) = @_;
my $ret = 1;
foreach my $arg (qw(githubClientID githubClientSecret)) {
unless ( $self->conf->{$arg} ) {
$ret = 0;
lib/Lemonldap/NG/Portal/Auth/GitHub.pm view on Meta::CPAN
if ($@) {
$self->logger->error(
"Unable to decode JSON $public_keys_content");
return PE_ERROR;
}
$req->data->{githubData}->{"public_keys"} = $json_hash;
}
# Fetch GPG keys
if ( $self->conf->{githubScope} =~ /gpg_key/ ) {
$self->logger->debug("Scope gpg_key requested, fetch SSH keys");
my $gpg_keys_response =
$self->ua->get( $self->githubGPGKeysEndpoint,
"Authorization" => "token $access_token" );
if ( $gpg_keys_response->is_error ) {
$self->logger->error( "Bad authorization response: "
. $gpg_keys_response->message );
$self->logger->debug( $gpg_keys_response->content );
return PE_ERROR;
}
my $gpg_keys_content = $gpg_keys_response->decoded_content;
$self->logger->debug(
"Response from GitHub GPG Keys API: $gpg_keys_content");
eval {
$json_hash =
from_json( $gpg_keys_content, { allow_nonref => 1 } );
};
if ($@) {
$self->logger->error("Unable to decode JSON $gpg_keys_content");
return PE_ERROR;
}
$req->data->{githubData}->{"gpg_keys"} = $json_hash;
}
# Extract state
if ($state) {
my $stateSession = $self->p->getApacheSession( $state, 1 );
$req->urldc( $stateSession->data->{urldc} );
$req->{checkLogins} = $stateSession->data->{checkLogins};
$stateSession->remove;
lib/Lemonldap/NG/Portal/Main/Display.pm view on Meta::CPAN
DISPLAY_FORM => $displayType =~ /\bstandardform\b/ ? 1
: 0,
DISPLAY_OPENID_FORM => $displayType =~ /\bopenidform\b/ ? 1
: 0,
DISPLAY_YUBIKEY_FORM => $displayType =~ /\byubikeyform\b/
? 1
: 0,
DISPLAY_SSL_FORM => $displayType =~ /sslform/ ? 1 : 0,
DISPLAY_WEBAUTHN_FORM => $displayType =~ /webauthnform/ ? 1
: 0,
DISPLAY_GPG_FORM => $displayType =~ /gpgform/ ? 1 : 0,
DISPLAY_LOGO_FORM => $displayType eq "logo" ? 1 : 0,
DISPLAY_FINDUSER => scalar @$fields,
module => $displayType eq "logo"
? $self->getModule( $req, 'auth' )
: "",
AUTH_LOOP => [],
PORTAL_URL => ( $displayType eq "logo" ? $req->portal : 0 ),
MSG => $req->info(),
MANDATORY => $mandatory,
FIELDS => $fields,
site/templates/bootstrap/gpgform.tpl view on Meta::CPAN
<span trspan="Please sign the following text with your GPG key"></span>
<pre>echo -n "<TMPL_VAR NAME="TOKEN">"| gpg --clear-sign</pre>
<div class="form">
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text"><label for="userfield" class="mb-0"><i class="fa fa-user"></i></label></span>
</div>
<input id="userfield" name="user" type="text" class="form-control" value="<TMPL_VAR NAME="LOGIN" ESCAPE=HTML>" trplaceholder="mail" required aria-required="true" />
</div>
<div class="input-group mb-3">
<div class="input-group-prepend">
site/templates/bootstrap/login.tpl view on Meta::CPAN
<TMPL_IF NAME="webauthnform">
<TMPL_INCLUDE NAME="webauthnform.tpl">
<!-- Remember my authentication choice for this module -->
<TMPL_IF NAME="REMEMBERAUTHCHOICE">
<input type="hidden" id="rememberauthchoice" name="rememberauthchoice" value="<TMPL_IF NAME="REMEMBERAUTHCHOICEDEFAULTCHECKED">true</TMPL_IF>" />
</TMPL_IF>
</TMPL_IF>
<TMPL_IF NAME="gpgform">
<TMPL_INCLUDE NAME="gpgform.tpl">
</TMPL_IF>
<TMPL_IF NAME="logo">
<div class="form">
<TMPL_IF NAME="logoFile">
<img src="<TMPL_VAR NAME="STATIC_PREFIX">common/modules/<TMPL_VAR NAME="logoFile">" alt="<TMPL_VAR NAME="module">" class="img-thumbnail mb-3" />
</TMPL_IF>
site/templates/bootstrap/login.tpl view on Meta::CPAN
<TMPL_IF NAME="module">
<form id="lform" action="#" method="post" class="login <TMPL_VAR NAME="module">" role="form">
<TMPL_ELSE>
<form id="lform" action="#" method="post" class="login" role="form">
</TMPL_IF>
<!-- Hidden fields -->
<TMPL_VAR NAME="HIDDEN_INPUTS">
<input type="hidden" name="url" value="<TMPL_VAR NAME="AUTH_URL">" />
<input type="hidden" name="timezone" />
<input type="hidden" name="skin" value="<TMPL_VAR NAME="SKIN">" />
<TMPL_INCLUDE NAME="gpgform.tpl">
</form>
</div>
</TMPL_IF>
<TMPL_IF NAME="DISPLAY_YUBIKEY_FORM">
<div class="card">
<TMPL_IF NAME="module">
<form id="lform" action="#" method="post" class="login <TMPL_VAR NAME="module">" role="form">
<TMPL_ELSE>
<form id="lform" action="#" method="post" class="login" role="form">
t/28-AuthChoice-and-password.t view on Meta::CPAN
authentication => 'Choice',
userDB => 'Same',
passwordDB => 'Choice',
portalRequireOldPassword => 1,
authChoiceParam => 'test',
authChoiceModules => {
ldap => 'LDAP;LDAP;LDAP',
sql => 'DBI;DBI;DBI',
slave => 'Slave;LDAP;LDAP',
gpg => 'GPG;Demo;Null'
},
dbiAuthChain => "dbi:SQLite:dbname=$userdb",
dbiAuthUser => '',
dbiAuthPassword => '',
dbiAuthTable => 'users',
dbiAuthLoginCol => 'user',
dbiAuthPasswordCol => 'password',
dbiAuthPasswordHash => '',
t/29-AuthGPG.t view on Meta::CPAN
use strict;
require 't/test-lib.pm';
my $mainTests = 5;
SKIP: {
skip "Manual skip of GPG test", $mainTests if ( $ENV{LLNG_SKIP_GPG_TEST} );
eval "use IPC::Run 0.93 'run',";
skip "Missing dependency", $mainTests if ($@);
my $gpg = eval { `which gpg` };
skip "Missing gpg", $mainTests if $@ or not $gpg;
chomp $gpg;
my $res;
use_ok('Lemonldap::NG::Common::FormEncode');
my $client = LLNG::Manager::Test->new( {
ini => {
logLevel => 'error',
authentication => 'GPG',
userDB => 'Null',
gpgDb => 't/gpghome/key.asc',
requireToken => 1,
}
}
);
ok( $res = $client->_get( '/', accept => 'text/html' ), 'First access' );
my ( $host, $url, $query ) =
expectForm( $res, '#', undef, 'user', 'token' );
$query =~ s/user=/user=llng\@lemonldap-ng.org/;
$query =~ /token=([^&]+)/;
my $token = $1 or fail('No token');
ok( $res->[2]->[0] =~ /echo -n "$token"/m, "Found instructions" );
my ( $out, $err );
run( [ 'gpg', '--clear-sign', '--homedir', 't/gpghome' ],
\$token, \$out, \$err, IPC::Run::timeout(10) );
if ( $? == 0 ) {
pass 'Succeed to sign';
}
else {
run( [ 'gpg', '--clearsign', '--homedir', 't/gpghome' ],
\$token, \$out, \$err, IPC::Run::timeout(10) );
unless ( $? == 0 ) {
skip "Local GPG signature fails, aborting", 2;
}
pass("Succeed to sign");
}
$query .= '&' . build_urlencoded( password => $out );
ok(
$res = $client->_post(
'/',
t/gpghome/openpgp-revocs.d/9482CEFB055809CBAFE6D71AAB2D5542891D1677.rev view on Meta::CPAN
uid LL::NG <llng@lemonldap-ng.org>
A revocation certificate is a kind of "kill switch" to publicly
declare that a key shall not anymore be used. It is not possible
to retract such a revocation certificate once it has been published.
Use it to revoke this key in case of a compromise or loss of
the secret key. However, if the secret key is still accessible,
it is better to generate a new revocation certificate and give
a reason for the revocation. For details see the description of
of the gpg command "--generate-revocation" in the GnuPG manual.
To avoid an accidental use of this file, a colon has been inserted
before the 5 dashes below. Remove this colon with a text editor
before importing and publishing this revocation certificate.
:-----BEGIN PGP PUBLIC KEY BLOCK-----
Comment: This is a revocation certificate
iQG2BCABCgAgFiEElILO+wVYCcuv5tcaqy1VQokdFncFAlwG+U8CHQAACgkQqy1V
QokdFndF6Qv+Pk5xMIXm43dXghosAJZQTI1VvCDDmfhvSedoU+bweANKvnnugLnA