parent
1f14ed9dfe
commit
f6459b7985
@ -0,0 +1,10 @@
|
||||
INCLUDES= $(all_includes) $(KDE_INCLUDES)/tde
|
||||
|
||||
bin_PROGRAMS = tdeldapcertupdater
|
||||
|
||||
tdeldapcertupdater_SOURCES = main.cpp
|
||||
|
||||
tdeldapcertupdater_METASOURCES = AUTO
|
||||
tdeldapcertupdater_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LIB_QT) -lDCOP $(LIB_TDECORE) $(LIB_TDEUI) -ltdefx $(LIB_KIO) -ltdetexteditor -ltdeldap
|
||||
|
||||
KDE_OPTIONS = nofinal
|
@ -0,0 +1,211 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2013 by Timothy Pearson *
|
||||
* kb9vqf@pearsoncomputing.net *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <csignal>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <netdb.h>
|
||||
#include <pwd.h>
|
||||
|
||||
#include <tdeapplication.h>
|
||||
#include <tdestartupinfo.h>
|
||||
#include <tdecmdlineargs.h>
|
||||
#include <tdeaboutdata.h>
|
||||
|
||||
#include <ksimpleconfig.h>
|
||||
|
||||
#include <tqdatetime.h>
|
||||
#include <tqfile.h>
|
||||
#include <tqdir.h>
|
||||
|
||||
#include <libtdeldap.h>
|
||||
|
||||
// FIXME
|
||||
// Connect this to CMake/Automake
|
||||
#define KDE_CONFDIR "/etc/trinity"
|
||||
|
||||
static const char description[] =
|
||||
I18N_NOOP("TDE utility for updating realm certificates");
|
||||
|
||||
static const char version[] = "v0.0.1";
|
||||
|
||||
bool received_sighup = false;
|
||||
|
||||
void signalHandler(int signum)
|
||||
{
|
||||
printf("[INFO] Got signal %d\n\r", signum);
|
||||
if (signum == SIGHUP) {
|
||||
received_sighup = true;
|
||||
}
|
||||
else if (signum == SIGTERM) {
|
||||
unlink(TDE_LDAP_CERT_UPDATER_PID_FILE);
|
||||
exit(0);
|
||||
}
|
||||
else if (signum == SIGINT) {
|
||||
unlink(TDE_LDAP_CERT_UPDATER_PID_FILE);
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
int get_certificate_from_server(TQString certificateName, LDAPRealmConfig realmcfg)
|
||||
{
|
||||
int retcode = 0;
|
||||
TQString errorstring;
|
||||
|
||||
// Bind anonymously to LDAP
|
||||
LDAPCredentials* credentials = new LDAPCredentials;
|
||||
credentials->username = "";
|
||||
credentials->password = "";
|
||||
credentials->realm = realmcfg.name.upper();
|
||||
credentials->use_tls = false;
|
||||
LDAPManager* ldap_mgr = new LDAPManager(realmcfg.name.upper(), TQString("ldap://%1").arg(realmcfg.admin_server).ascii(), credentials);
|
||||
|
||||
// Add the domain-wide computer local admin group to local sudoers
|
||||
ldap_mgr->writeSudoersConfFile(&errorstring);
|
||||
|
||||
// Get and install the CA root certificate from LDAP
|
||||
printf("[INFO] Updating certificate %s from LDAP\n\r", certificateName.ascii());
|
||||
if (ldap_mgr->getTDECertificate("publicRootCertificate", certificateName, &errorstring) != 0) {
|
||||
printf("[ERROR] Unable to obtain root certificate for realm %s: %s", realmcfg.name.upper().ascii(), errorstring.ascii());
|
||||
retcode = 1;
|
||||
}
|
||||
|
||||
delete ldap_mgr;
|
||||
delete credentials;
|
||||
|
||||
return retcode;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// Register signal handler for SIGHUP
|
||||
signal(SIGHUP, signalHandler);
|
||||
// Register signal handler for SIGINT
|
||||
signal(SIGINT, signalHandler);
|
||||
// Register signal handler for SIGTERM
|
||||
signal(SIGTERM, signalHandler);
|
||||
|
||||
TQDir pidDir(TDE_LDAP_PID_DIR);
|
||||
if (!pidDir.exists()) {
|
||||
mkdir(TDE_LDAP_PID_DIR, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
|
||||
}
|
||||
TQFile pidFile(TDE_LDAP_CERT_UPDATER_PID_FILE);
|
||||
if (pidFile.open(IO_WriteOnly)) {
|
||||
TQTextStream stream(&pidFile);
|
||||
stream << getpid();
|
||||
pidFile.close();
|
||||
}
|
||||
|
||||
// Seed random number generator
|
||||
struct timeval time;
|
||||
gettimeofday(&time,NULL);
|
||||
srand((time.tv_sec * 1000) + (time.tv_usec / 1000));
|
||||
|
||||
// Initialize TDE application libraries
|
||||
TDEAboutData aboutData( "tdeldapcertupdater", I18N_NOOP("Realm Certificate Updater"),
|
||||
version, description, TDEAboutData::License_GPL,
|
||||
"(c) 2013, Timothy Pearson");
|
||||
aboutData.addAuthor("Timothy Pearson",0, "kb9vqf@pearsoncomputing.net");
|
||||
TDECmdLineArgs::init( argc, argv, &aboutData );
|
||||
TDEApplication::disableAutoDcopRegistration();
|
||||
|
||||
TDEApplication app(false, false);
|
||||
|
||||
TDEStartupInfo::appStarted();
|
||||
|
||||
//======================================================================================================================================================
|
||||
//
|
||||
// Updater code follows
|
||||
//
|
||||
//======================================================================================================================================================
|
||||
|
||||
KSimpleConfig* systemconfig = new KSimpleConfig( TQString::fromLatin1( KDE_CONFDIR "/ldap/ldapconfigrc" ));
|
||||
LDAPRealmConfigList realms = LDAPManager::readTDERealmList(systemconfig, false);
|
||||
TQString m_defaultRealm = systemconfig->readEntry("DefaultRealm");
|
||||
|
||||
int prevSecondsToExpiry = (7*24*60*60);
|
||||
|
||||
while (1) {
|
||||
bool allDownloadsOK = true;
|
||||
TQDateTime now = TQDateTime::currentDateTime();
|
||||
TQDateTime earliestCertExpiry = now.addDays(14); // Recheck every 7 days regardless of last expiry check results
|
||||
|
||||
LDAPRealmConfigList::Iterator it;
|
||||
for (it = realms.begin(); it != realms.end(); ++it) {
|
||||
LDAPRealmConfig realmcfg = it.data();
|
||||
TQString certificateName = KERBEROS_PKI_PUBLICDIR + realmcfg.admin_server + ".ldap.crt";
|
||||
|
||||
TQDateTime certExpiry;
|
||||
TQDateTime soon = now.addDays(7); // Keep in sync with src/ldapcontroller.cpp
|
||||
|
||||
if (TQFile::exists(certificateName)) {
|
||||
certExpiry = LDAPManager::getCertificateExpiration(certificateName);
|
||||
if (certExpiry >= now) {
|
||||
printf("[INFO] Certificate %s expires %s\n\r", certificateName.ascii(), certExpiry.toString().ascii()); fflush(stdout);
|
||||
}
|
||||
if ((certExpiry < now) || ((certExpiry >= now) && (certExpiry < soon))) {
|
||||
if (get_certificate_from_server(certificateName, realmcfg) != 0) {
|
||||
allDownloadsOK = false;
|
||||
}
|
||||
}
|
||||
if (certExpiry < earliestCertExpiry) {
|
||||
earliestCertExpiry = certExpiry;
|
||||
}
|
||||
}
|
||||
else {
|
||||
mkdir(TDE_CERTIFICATE_DIR, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
|
||||
mkdir(KERBEROS_PKI_PUBLICDIR, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
|
||||
if (get_certificate_from_server(certificateName, realmcfg) != 0) {
|
||||
allDownloadsOK = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
earliestCertExpiry = earliestCertExpiry.addDays(-7); // Keep in sync with now.addDays above (use negative of value given above)
|
||||
int secondsToExpiry = now.secsTo(earliestCertExpiry);
|
||||
secondsToExpiry = secondsToExpiry + (rand()%(5*60)); // Nothing worse than thousands of clients hammering the LDAP server all at once...
|
||||
if (secondsToExpiry < 1) {
|
||||
secondsToExpiry = 1;
|
||||
}
|
||||
if ((prevSecondsToExpiry == 1) && (allDownloadsOK)) {
|
||||
// The server has not yet updated its certificate, even though our copy is close to expiration
|
||||
// Therefore, do not hammer the server with useless requests!
|
||||
prevSecondsToExpiry = (15*60) + (rand()%(5*60));
|
||||
}
|
||||
prevSecondsToExpiry = secondsToExpiry;
|
||||
printf("[INFO] Will recheck certificates in %d seconds (%d days)\n\r", secondsToExpiry, secondsToExpiry/60/60/24); fflush(stdout);
|
||||
if (sleep(secondsToExpiry) != 0) {
|
||||
// Signal caught
|
||||
if (!received_sighup) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unlink(TDE_LDAP_CERT_UPDATER_PID_FILE);
|
||||
|
||||
//======================================================================================================================================================
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in new issue