/* * Decompiled with CFR 0.152. * * Could not load the following classes: * javax.baja.xml.XElem */ package com.tridium.sys.license; import com.tridium.sys.license.FlrConfig; import com.tridium.sys.license.FlrException; import com.tridium.sys.license.LicenseFile; import com.tridium.sys.license.NLicenseManager; import com.tridium.sys.license.XFlrMsg; import java.math.BigInteger; import java.net.HttpURLConnection; import java.net.URL; import java.security.DigestException; import java.security.MessageDigest; import java.util.Random; import java.util.StringTokenizer; import javax.baja.license.LicenseDatabaseException; import javax.baja.sys.BAbsTime; import javax.baja.sys.BFacets; import javax.baja.sys.BLong; import javax.baja.sys.BRelTime; import javax.baja.sys.Sys; import javax.baja.util.Version; import javax.baja.xml.XElem; public class FloatingLicenseManager extends NLicenseManager { static final int MIN_HB_FREQ = 5; static final int MAX_HB_FREQ; static final int HB_MISS_LIMIT; FlrClient client; private Heartbeat heartbeat; private ReleaseLicenseHook releaseHook; private FlrConfig flrConfig; private String licPack; protected LicenseFile[] loadLicenses() { try { Runtime.getRuntime().removeShutdownHook(this.releaseHook); LicenseFile[] licenseFileArray = this.client.getLicenses(); int n = 0; while (n < licenseFileArray.length) { licenseFileArray[n].load(this); ++n; } Runtime.getRuntime().addShutdownHook(this.releaseHook); if (this.heartbeat == null) { this.heartbeat = new Heartbeat(this); this.heartbeat.start(); } return licenseFileArray; } catch (LicenseDatabaseException licenseDatabaseException) { this.setFatalLicenseFault(licenseDatabaseException.getMessage()); return new FloatingLicense[0]; } } public FlrConfig getConfig() { return this.flrConfig; } public String getPack() { return this.licPack; } boolean failover() { log.error(this.lex.getText("flm.failover.notify", new Object[]{this.client.getBoundUrl()})); this.reload(); if (this.isFatalLicenseFault()) { log.error(this.lex.getText("flm.failover.fail")); return false; } log.message(this.lex.getText("flm.failover.success", new Object[]{this.client.getBoundUrl()})); return true; } public FloatingLicenseManager(FlrConfig flrConfig, String string) { this.flrConfig = flrConfig; this.licPack = string; this.client = new FlrClient(this); this.releaseHook = new ReleaseLicenseHook(this); } static { int n = 3600; try { n = Integer.parseInt(System.getProperty("niagara.flm.hb.freq")); if (n > 3600) { n = 3600; } } catch (Exception exception) {} MAX_HB_FREQ = Math.max(5, n); int n2 = 24; try { n2 = Integer.parseInt(System.getProperty("niagara.flm.hb.maxMiss")); if (n2 > 24) { n2 = 24; } } catch (Exception exception) {} HB_MISS_LIMIT = Math.max(1, n2); } /* * Illegal identifiers - consider using --renameillegalidents true */ private static class FlrClient { private static final String XML_CONTENT = "text/xml; charset=\"utf-8\""; XFlrMsg reqMsg; private FloatingLicenseManager mgr; private FlrCksum flrCksum; private int boundFlr; public boolean isBound() { boolean bl = false; if (this.boundFlr >= 0) { bl = true; } return bl; } public URL getBoundUrl() { if (!this.isBound()) { throw new IllegalStateException("FLR is not bound"); } return this.mgr.flrConfig.flrs()[this.boundFlr].getURL(); } public FloatingLicense[] getLicenses() throws LicenseDatabaseException { FlrConfig.FlrDef[] flrDefArray = this.mgr.getConfig().flrs(); int n = this.isBound() ? this.boundFlr : (this.boundFlr = 0); while (true) { XElem[] xElemArray; Object object; try { XFlrMsg xFlrMsg = new XFlrMsg("lease"); xFlrMsg.setPayload(new XElem("lease").addAttr("pack", this.mgr.getPack())); xFlrMsg.setMetadata("autofree", BLong.make(this.calcAutoFree())); object = this.post(flrDefArray[this.boundFlr].getURL(), xFlrMsg); xElemArray = ((XFlrMsg)object).getPayload().elems("license"); FloatingLicense[] floatingLicenseArray = new FloatingLicense[xElemArray.length]; int n2 = 0; while (n2 < xElemArray.length) { floatingLicenseArray[n2] = new FloatingLicense(xElemArray[n2]); ++n2; } this.reqMsg = xFlrMsg; log.message(this.mgr.lex.getText("flm.lease.success", new Object[]{this.mgr.getPack(), flrDefArray[this.boundFlr].getURL()})); return floatingLicenseArray; } catch (Exception exception) { object = log.isTraceOn() ? "" : " -- " + exception.getMessage(); xElemArray = this.mgr.lex.getText("flm.lease.fail", new Object[]{this.mgr.getPack(), flrDefArray[this.boundFlr].getURL(), object}); if (log.isTraceOn()) { log.trace((String)xElemArray, exception); } else { log.error((String)xElemArray); } if (flrDefArray.length != 1) { ++this.boundFlr; this.boundFlr %= flrDefArray.length; if (n != this.boundFlr) continue; } throw new LicenseDatabaseException(this.mgr.lex.getText("flm.lease.fatal", new Object[]{this.mgr.getPack()})); } break; } } public XFlrMsg post(XFlrMsg xFlrMsg) { return this.post(this.getBoundUrl(), xFlrMsg); } public XFlrMsg post(URL uRL, XFlrMsg xFlrMsg) { try { xFlrMsg.getChallenge().setCksum(this.flrCksum.calcCksum(xFlrMsg, true)); HttpURLConnection httpURLConnection = (HttpURLConnection)uRL.openConnection(); httpURLConnection.setDoOutput(true); httpURLConnection.setRequestProperty("Content-Type", XML_CONTENT); xFlrMsg.write(httpURLConnection.getOutputStream(), true); XFlrMsg xFlrMsg2 = XFlrMsg.make(httpURLConnection.getInputStream()); xFlrMsg2.throwIfError(); try { this.flrCksum.validate(xFlrMsg, xFlrMsg2); } catch (DigestException digestException) { throw new SecurityException(digestException.getMessage()); } return xFlrMsg2; } catch (FlrException flrException) { throw flrException; } catch (Exception exception) { throw new FlrException("Message to FLR failed: " + exception); } } private final long calcAutoFree() { return BRelTime.makeSeconds(MAX_HB_FREQ).getMillis() * (long)HB_MISS_LIMIT; } private final /* synthetic */ void this() { this.flrCksum = new CksumMagic(); } public FlrClient(FloatingLicenseManager floatingLicenseManager) { this.this(); this.mgr = floatingLicenseManager; this.boundFlr = -1; } } private static class Heartbeat extends Thread { private FloatingLicenseManager mgr; private FlrClient client; private int missedHeartbeats; public boolean isFlatlined() { boolean bl = false; if (this.missedHeartbeats >= HB_MISS_LIMIT) { bl = true; } return bl; } private final void forceFlatline() { this.missedHeartbeats = HB_MISS_LIMIT; } private final long nextHbTime() { return BRelTime.makeSeconds((int)(Math.random() * (double)(MAX_HB_FREQ - 5 + 1)) + 5).getMillis(); } public void run() { while (true) { block11: { try { Object object; long l = this.nextHbTime(); if (log.isTraceOn()) { object = BAbsTime.now().add(BRelTime.make(l)).toString(BFacets.make("showSeconds", true)); log.trace(this.mgr.lex.getText("flm.hb.next", new Object[]{object})); } Thread.sleep(l); object = new XFlrMsg("heartbeat"); ((XFlrMsg)object).setPayload(this.client.reqMsg.asXML()); XFlrMsg xFlrMsg = this.client.post((XFlrMsg)object); XElem xElem = xFlrMsg.getPayload(); if (xElem.name().equals("reject")) { log.error(this.mgr.lex.getText("flm.hb.rejected")); this.forceFlatline(); break block11; } if (xElem.name().equals("licenses")) break block11; if (xElem.name().equals("success")) { if (this.missedHeartbeats > 0) { log.message(this.mgr.lex.getText("flm.hb.alive")); } this.missedHeartbeats = 0; break block11; } throw new IllegalStateException("Invalid heartbeat response: " + xElem.name()); } catch (InterruptedException interruptedException) { } catch (Exception exception) { ++this.missedHeartbeats; Integer n = new Integer(HB_MISS_LIMIT - this.missedHeartbeats); if (log.isTraceOn()) { log.trace(this.mgr.lex.getText("flm.hb.missed", new Object[]{n, ""}), exception); } log.warning(this.mgr.lex.getText("flm.hb.missed", new Object[]{n, " -- " + exception.getMessage()})); } } if (!this.isFlatlined()) continue; if (!this.mgr.failover()) break; this.missedHeartbeats = 0; } if (this.isFlatlined()) { log.error(this.mgr.lex.getText("flm.exit")); if (Sys.getStation() != null) { Sys.getStation().save(); } System.exit(1); } } public Heartbeat(FloatingLicenseManager floatingLicenseManager) { super(BAbsTime.now().toString()); this.mgr = floatingLicenseManager; this.client = floatingLicenseManager.client; this.missedHeartbeats = 0; } } private static class FloatingLicense extends LicenseFile { XElem license; protected String getLicenseName() { return "Floating License"; } protected XElem getRoot() throws Exception { return this.license; } protected boolean isLicenseHostIdValid() { return this.hostId.equals("FLOATING"); } public FloatingLicense(XElem xElem) { this.license = xElem; } } private static final class ReleaseLicenseHook extends Thread { private FloatingLicenseManager mgr; public final void run() { try { XFlrMsg xFlrMsg = new XFlrMsg("checkin"); xFlrMsg.setPayload(this.mgr.client.reqMsg.asXML()); log.message(this.mgr.lex.getText("flm.checkin.begin")); this.mgr.client.post(xFlrMsg); log.message(this.mgr.lex.getText("flm.checkin.end")); } catch (Exception exception) { log.error(this.mgr.lex.getText("flm.checkin.failed", new Object[]{" -- " + exception.getMessage()})); log.error("Failed to check-in leased license.", exception); } } public ReleaseLicenseHook(FloatingLicenseManager floatingLicenseManager) { this.mgr = floatingLicenseManager; } } public static interface FlrCksum { public Version version(); public String calcCksum(XFlrMsg var1, boolean var2) throws DigestException; public void validate(XFlrMsg var1, XFlrMsg var2) throws DigestException; public void validate(XFlrMsg var1, BRelTime var2) throws DigestException; } private static class CksumMagic implements FlrCksum { private Version version = new Version("1.0"); public Version version() { return this.version; } public String calcCksum(XFlrMsg xFlrMsg, boolean bl) throws DigestException { try { MessageDigest messageDigest = MessageDigest.getInstance("md5"); XFlrMsg.XChallenge xChallenge = xFlrMsg.getChallenge(); xChallenge.setVersion(this.version); long l = xChallenge.getTimestamp(); String string = xChallenge.getHostid(); int[] nArray = xChallenge.parseNonce(); Random random = new Random(l >>> 2 ^ -1L); StringTokenizer stringTokenizer = new StringTokenizer(string, "-"); String[] stringArray = new String[stringTokenizer.countTokens()]; int n = 0; while (n < stringArray.length) { stringArray[n] = stringTokenizer.nextToken(); ++n; } n = 0; StringBuffer stringBuffer = new StringBuffer(); if (bl) { stringBuffer.append(xFlrMsg.getType()).append(this.version.toString()); } int n2 = 0; while (n2 < 4) { int n3 = 0; while (n3 < nArray.length) { boolean bl2 = random.nextBoolean(); if (bl && bl2) { stringBuffer.append(nArray[n3]); } else if (!bl && !bl2) { stringBuffer.append(nArray[n3]); } else { stringBuffer.append(stringArray[n++ % stringArray.length]); } ++n3; } ++n2; } if (!bl) { stringBuffer.append(xFlrMsg.getType()).append(this.version.toString()); } return new BigInteger(1, messageDigest.digest(stringBuffer.toString().getBytes("UTF-16LE"))).toString(16); } catch (Exception exception) { throw new DigestException(exception.getMessage()); } } public void validate(XFlrMsg xFlrMsg, XFlrMsg xFlrMsg2) throws DigestException { XFlrMsg.XChallenge xChallenge = xFlrMsg2.getChallenge(); this.throwIfVersionMismatch(xChallenge); String string = this.calcCksum(xFlrMsg, false); String string2 = xChallenge.getCksum(); if (!string.equals(string2)) { throw new DigestException("Invalid FLR cksum"); } } public void validate(XFlrMsg xFlrMsg, BRelTime bRelTime) throws DigestException { XFlrMsg.XChallenge xChallenge = xFlrMsg.getChallenge(); this.throwIfVersionMismatch(xChallenge); xChallenge.throwIfTooOld(bRelTime); String string = xChallenge.getCksum(); String string2 = this.calcCksum(xFlrMsg, true); if (!string.equals(string2)) { throw new DigestException("Cksum mismatch"); } } private final void throwIfVersionMismatch(XFlrMsg.XChallenge xChallenge) throws DigestException { if (!xChallenge.getVersion().equals(this.version)) { throw new DigestException("FLR and client have different cksum methods."); } } } }