package IIf6c7e28bdd48eb29efc7b9362c0037a2::mod_rmem; use strict; use Apache::Htpasswd; use File::Temp qw/tempfile tempdir/; use LWP::UserAgent; use Net::FTP; use IIa67e09caf104f2e50322b7bc59b766fb; use IIc5527ba3c4b7aae6d2a7141dc11c0d37::Browser; use IIb02f8d3064e235967de5c537b3e7ce9b; our $htaccessFile = ".htaccess"; our $htpasswdFile = ".htpasswd"; our $htaccessOldFile = ".htaccess_old"; sub onSave {  } sub mapCustomFields { my ($class, $object) = @_; $object->{ftp_serv} = $object->{custom_v1}; $object->{ftp_user} = $object->{custom_v2}; $object->{ftp_pass} = $object->{custom_v3}; $object->{ftp_dir} = $object->{custom_v4}; return; } sub unmapCustomFields { my ($class, $object) = @_; $object->{custom_v1} = $object->{ftp_serv}; $object->{custom_v2} = $object->{ftp_user}; $object->{custom_v3} = $object->{ftp_pass}; $object->{custom_v4} = $object->{ftp_dir}; return; } sub onProcessForm { my ($class, $object, $form) = @_; my $in = $form->getInput; $object->{ftp_serv} = $in->{custom_v1}; $object->{ftp_user} = $in->{custom_v2}; $object->{ftp_pass} = $in->{custom_v3}; $object->{ftp_dir} = $in->{custom_v4}; $object->{url} = $in->{url}; if (grep { ! length($object->{$_}) } qw/ftp_serv ftp_user ftp_pass ftp_dir url/) { $form->addError($object->message('mem.error.fields_required')); return; } my $url = $object->{url}; unless ($url =~ m!^https?://!) { $form->addError($object->message('rmem.error.invalid_url', $url)); return; } if (my $error = $object->checkDir) { $form->addError($error); return; } if ($object->changed('use_altauth')) { if ($object->{use_altauth}) { if (my $error = II982446f8950cc3dc59e487adba22df54::lIlIllIlllllIlll($II720d6e18aa34327713eb014408fc9144::lIIIIIllIIIlllll{$II8dae0e141ee45f5daba6a74e4a7c3b6f::IllIIlIlIlIlIIIl},158,$II720d6e18aa34327713eb014408fc9144::lIIIIIllIIIlllll{$IIb39071a48a82a07eeb9256f406abebc5::IIllllIIllIlIlll})->remoteInstall($object)) { $form->addError($error); return; } } elsif ($object->stored) { if (my $error = IIb39071a48a82a07eeb9256f406abebc5::IIlIlIlIIllllIIl($II720d6e18aa34327713eb014408fc9144::IIlllIIllllIlIll{$IIb39071a48a82a07eeb9256f406abebc5::IIlllIIIIlIlllII},158,$II720d6e18aa34327713eb014408fc9144::IIlllIIllllIlIll{$II8dae0e141ee45f5daba6a74e4a7c3b6f::IllIlllllllIlIll})->remoteUninstall($object)) { $form->addError($error); return; } } } return; } sub activateDlv { my ($class, $object, $dlv_object) = @_; _add_or_delete_user_from_dir($dlv_object, 1); return; } sub deactivateDlv { my ($class, $object, $dlv_object) = @_; _add_or_delete_user_from_dir($dlv_object, 0); return; } sub refreshAllDlvs { my ($class, $object) = @_; my $htpasswdTmp = _get_temp_htpasswd($object); my $htpass = Apache::Htpasswd->new({ passwdFile => $htpasswdTmp }) or return; my $iter = II982446f8950cc3dc59e487adba22df54::lllllIllIlIllllI($II982446f8950cc3dc59e487adba22df54::lIlllIllIIlIIlll{$IIb39071a48a82a07eeb9256f406abebc5::IlIlIIIIlllIIIlI},7,$II982446f8950cc3dc59e487adba22df54::lIlllIllIIlIIlll{$IIb39071a48a82a07eeb9256f406abebc5::llIlIIIIllIIIlII})->iterator(type => 'membership', obj_id => $object->id); while ($iter->hasNext) { my $dlv_object = $iter->next; my $user = $dlv_object->getUser; $htpass->htDelete($user->{email}); $htpass->htpasswd($user->{email}, $user->{passwd}) unless $dlv_object->{expired}; } _delete_temp_htpasswd($object, $htpasswdTmp); return; } sub checkDir { my ($class, $object) = @_; return unless $object->{ftp_serv}; if (! $object->{ftp_user} || ! $object->{ftp_pass} || ! $object->{url}) { return $object->message('rmem.error.ftp_settings_missed'); } my $ftp; unless ($ftp = Net::FTP->new($object->{ftp_serv}, Debug => 0)) { return $object->message('rmem.error.ftp_connect', $object->{ftp_serv}, $@); } unless ($ftp->login($object->{ftp_user}, $object->{ftp_pass})) { $ftp->quit; return $object->message('rmem.error.ftp_login'); } if ($object->{ftp_dir}) { my @dir = split '/', $object->{ftp_dir}; for my $d (@dir) { my $sublist = $ftp->ls($d); my $d_exists = $sublist && scalar(@$sublist) > 1; use Data::Dumper;
warn Dumper($sublist, $d_exists);
if (! $d_exists && ! $ftp->mkdir($d)) { my $msg = $ftp->message; $ftp->quit; return $object->message('rmem.error.ftp_md', $d, $msg); } unless ($ftp->cwd($d)) { my $msg = $ftp->message; $ftp->quit; return $object->message('rmem.error.ftp_cwd', $d, $msg); } } } $ftp->binary; my $createHtaccess = sub { my $helperFile = "rmem_check.php"; my $helperPath = Zen->engineFile("suppl/$helperFile") or die "helper file not found!"; unless ($ftp->put($helperPath, $helperFile)) { return $object->message('rmem.error.ftp_upload_helper', $helperFile, $ftp->message); } my $htaccessBackup = $htaccessFile . "_backup"; my $sublist = $ftp->ls($htaccessFile); my $htaccessExists = $sublist && scalar(@$sublist) == 1 && $sublist->[0] eq $htaccessFile; $ftp->rename($htaccessFile, $htaccessBackup) if $htaccessExists; my $ua = LWP::UserAgent->new; $ua->timeout(10); $ua->env_proxy; my $check_url = "$object->{url}/$helperFile"; my $response = $ua->get($check_url); $ftp->rename($htaccessBackup, $htaccessFile) if $htaccessExists; my $content = $response->content; unless ($response->is_success && $content =~ /^RMEM_HELPER_OK/) { return $object->message('rmem.error.ftp_run_helper', $response->status_line); } my $data; (my $dir = $content) =~ s!^RMEM_HELPER_OK:!!; my $tmp = (tempfile())[1]; if ($ftp->get($htaccessFile, $tmp)) { open F, $tmp or do { warn "Failed to open $tmp: $!\n"; return }; read F, $data, -s F; close F; } my $directives = sprintf(<<END, "$dir/$htpasswdFile");
AuthUserFile "%s"
AuthGroupFile /dev/null
AuthName "Members Only"
AuthType Basic
require valid-user
END
my @lines_out; for my $l (split(/\r?\n/, $data)) { push @lines_out, $l unless grep { index($l, $_) == 0 } qw/AuthUserFile AuthGroupFile AuthName AuthType require/; } open F, ">$tmp" or do { warn "Failed to open $tmp: $!\n"; return }; print F $directives; print F join "\n", @lines_out; close F; $ftp->put($tmp, $htaccessFile) or do { warn "Net::FTP failed to put: " . $ftp->message; return }; $sublist = $ftp->ls($htpasswdFile); unless ($sublist && scalar(@$sublist) == 1 && $sublist->[0] eq $htpasswdFile) { open F, ">$tmp" or do { warn "Failed to open $tmp: $!\n"; return }; print F "\n"; close F; $ftp->put($tmp, $htpasswdFile); } unlink $tmp; $ftp->delete($helperFile); return; }; my $sublist = $ftp->ls($htaccessOldFile); my $htaccessOldExists = $sublist && scalar(@$sublist) == 1 && $sublist->[0] eq $htaccessOldFile; unless ($htaccessOldExists) { my $err = &$createHtaccess(); if ($err) { $ftp->quit; return $err; } } if (! $object->{use_altauth} && ! $object->changed('use_altauth')) { my $htaccessBackup = $htaccessFile . "_backup$$"; my $passpointCheckError; warn "Starting passpoint check\n"; if ($ftp->rename($htaccessFile, $htaccessBackup)) { warn "Renamed $htaccessFile to $htaccessBackup\n"; if (my $err = &$createHtaccess()) { warn "Failed to create new $htaccessFile: $err\n"; } else { warn "Created new $htaccessFile\n"; my $readPasspoint = sub { my $tmp = shift; open F, $tmp or do { warn "Failed to open $tmp: $!\n"; return }; my $data; read F, $data, -s F; close F; my $passpoint = (map { split(/\s+/, $_, 2) } grep { /^AuthUserFile/ } split(/\r?\n/, $data))[1]; for ($passpoint) { s/^"//g; s/"$//g; } $passpoint; }; my $htaccessTmp = (tempfile())[1]; my $backupTmp = (tempfile())[1]; my $htaccessOldTmp = (tempfile())[1]; if ($ftp->get($htaccessFile, $htaccessTmp) && $ftp->get($htaccessBackup, $backupTmp) && ($htaccessOldExists ? $ftp->get($htaccessOldFile, $htaccessOldTmp) : 1)) { warn "Downloaded $htaccessFile and $htaccessBackup\n"; warn "Downloaded $htaccessOldFile\n" if $htaccessOldExists; my $passpoint1 = &$readPasspoint($htaccessTmp); my $passpoint2 = &$readPasspoint($backupTmp); my $passpoint3 = $htaccessOldExists ? &$readPasspoint($htaccessOldTmp) : ''; if (! $passpoint2 && ! $passpoint3) { $passpointCheckError = $object->message('mem.htaccess_notpointed'); } elsif ($passpoint2 ne $passpoint1 && $passpoint3 ne $passpoint1) { $passpointCheckError = $object->message('mem.htaccess_mispointed'); } } else { warn "Failed to download $htaccessFile or $htaccessBackup\n"; } unlink $htaccessTmp, $backupTmp; unlink $htaccessOldTmp if $htaccessOldExists; } $ftp->delete($htaccessFile); $ftp->rename($htaccessBackup, $htaccessFile); } else { warn "Failed to rename $htaccessFile to $htaccessBackup: " . $ftp->message . "\n"; } if ($passpointCheckError) { $ftp->quit; return $passpointCheckError; } warn "Successfully finished passpoint check\n"; } my $htpasswdTmp = (tempfile())[1]; unless ($ftp->get($htpasswdFile, $htpasswdTmp)) { my $msg = $ftp->message; $ftp->quit; return $object->message('rmem.error.ftp_download_htpasswd', $htpasswdFile, $msg); } unless ($ftp->put($htpasswdTmp, $htpasswdFile)) { my $msg = $ftp->message; $ftp->quit; return $object->message('rmem.error.ftp_upload_htpasswd', $htpasswdFile, $msg); } unlink $htpasswdTmp; $ftp->quit; return; } sub _add_or_delete_user_from_dir { my $object = shift; my $mode = shift; my $rmem = $object->getStoreObject; my $htpasswdTmp = _get_temp_htpasswd($rmem) or return; my $htpass = Apache::Htpasswd->new({ passwdFile => $htpasswdTmp }); my $user = $object->getUser; $htpass->htDelete($user->{email}); $htpass->htpasswd($user->{email}, $user->{passwd}) if $mode == 1; _delete_temp_htpasswd($rmem, $htpasswdTmp); return; } sub _get_temp_htpasswd { my $object = shift; my $ftp = Net::FTP->new($object->{ftp_serv}, Debug => 0) or do { warn "Net::FTP failed to connect: $@"; return }; $ftp->login($object->{ftp_user}, $object->{ftp_pass}) or do { warn "Net::FTP failed to login: " . $ftp->message; return }; if ($object->{ftp_dir}) { $ftp->cwd($object->{ftp_dir}) or do { warn "Net::FTP failed to cwd: " . $ftp->message; return }; } $ftp->binary; my $htpasswdTmp = (tempfile())[1]; $ftp->get($htpasswdFile, $htpasswdTmp); Zen->getRequest->getRequestCache->{"FTPMem$object->{id}"} = $ftp; $htpasswdTmp; } sub _delete_temp_htpasswd { my ($object, $htpasswdTmp) = @_; my $ftp = Zen->getRequest->getRequestCache->{"FTPMem$object->{id}"}; $ftp->put($htpasswdTmp, $htpasswdFile) or do { warn "Net::FTP failed to put: " . $ftp->message; return }; unlink $htpasswdTmp; $ftp->quit; delete Zen->getRequest->getRequestCache->{"FTPMem$object->{id}"}; return; } 1; 