Thu, 04 Oct 2012 20:30:05 +0200
Correct out of date build configuration, porting to Solaris 11 network
link infrastructure and new libpcap logic. This additionally allows for
device drivers in subdirectories of /dev. Correct packaged nmap
personalities and signatures to work out of the box. Finally, hack
arpd logic to properly close sockets and quit on TERM by repeating
signaling in the run command script. Sadly, all this fails to correct
the run time behaviour of honeyd which fails to bind to the IP layer.
michael@428 | 1 | -----BEGIN PGP SIGNED MESSAGE----- |
michael@428 | 2 | Hash: SHA1 |
michael@428 | 3 | |
michael@428 | 4 | - -- |
michael@428 | 5 | - -- OpenPKG Framework License Processor |
michael@428 | 6 | - -- Copyright (c) 2000-2012 OpenPKG GmbH <http://openpkg.com/> |
michael@428 | 7 | - -- |
michael@428 | 8 | - -- This software is property of the OpenPKG GmbH, DE MUC HRB 160208. |
michael@428 | 9 | - -- All rights reserved. Licenses which grant limited permission to use, |
michael@428 | 10 | - -- copy, modify and distribute this software are available from the |
michael@428 | 11 | - -- OpenPKG GmbH. |
michael@428 | 12 | - -- |
michael@428 | 13 | - -- THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED |
michael@428 | 14 | - -- WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
michael@428 | 15 | - -- MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
michael@428 | 16 | - -- IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR |
michael@428 | 17 | - -- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
michael@428 | 18 | - -- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
michael@428 | 19 | - -- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
michael@428 | 20 | - -- USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
michael@428 | 21 | - -- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
michael@428 | 22 | - -- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT |
michael@428 | 23 | - -- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
michael@428 | 24 | - -- SUCH DAMAGE. |
michael@428 | 25 | - -- |
michael@428 | 26 | |
michael@428 | 27 | - -- This is the RPM run-time integrity processor of the OpenPKG |
michael@428 | 28 | - -- Framework. It currently checks the OpenPKG Framework run-time |
michael@428 | 29 | - -- license only. The following grammar specifies and documents all |
michael@428 | 30 | - -- currently supported license parameters. |
michael@428 | 31 | - -- |
michael@428 | 32 | - -- license ::= "Assertion-MinProcVersion:" version |
michael@428 | 33 | - -- # require a minimum version of the license integrity processor |
michael@428 | 34 | - -- |
michael@428 | 35 | - -- | "Assertion-ErrorToWarning:" yes-no |
michael@428 | 36 | - -- # allow all fatal integrity checking errors to be |
michael@428 | 37 | - -- # converted to non-fatal warnings |
michael@428 | 38 | - -- |
michael@428 | 39 | - -- | "Assertion-OnlineApproval:" url |
michael@428 | 40 | - -- # require an online approval by receiving an "OK" from |
michael@428 | 41 | - -- # specified remote service |
michael@428 | 42 | - -- |
michael@428 | 43 | - -- | "Assertion-OnlineReporting:" url |
michael@428 | 44 | - -- # perform an asynchronous online reporting to |
michael@428 | 45 | - -- # specified remote service |
michael@428 | 46 | - -- |
michael@428 | 47 | - -- | "Assertion-Prefix:" path |
michael@428 | 48 | - -- # require %{l_prefix} to match specified path |
michael@428 | 49 | - -- |
michael@428 | 50 | - -- | "Assertion-User:" user |
michael@428 | 51 | - -- # require %{l_musr} to match specified username |
michael@428 | 52 | - -- |
michael@428 | 53 | - -- | "Assertion-Group:" group |
michael@428 | 54 | - -- # require %{l_mgrp} to match specified groupname |
michael@428 | 55 | - -- |
michael@428 | 56 | - -- | "Assertion-Domain:" domain |
michael@428 | 57 | - -- # require domain of host to match specified domain name |
michael@428 | 58 | - -- |
michael@428 | 59 | - -- | "Assertion-LifeTime:" iso-date.":".iso-date |
michael@428 | 60 | - -- # require current real-time to be within specified |
michael@428 | 61 | - -- # begin and end date |
michael@428 | 62 | - -- |
michael@428 | 63 | - -- | "Assertion-GrantTime:" iso-date.":".iso-date |
michael@428 | 64 | - -- # require current OpenPKG Framework %{RELEASE} |
michael@428 | 65 | - -- # (release time) to be within specified begin and end |
michael@428 | 66 | - -- # date |
michael@428 | 67 | - -- |
michael@428 | 68 | - -- | "Assertion-InstanceAge:" duration |
michael@428 | 69 | - -- # require current OpenPKG Framework %{ORIGINTIME} |
michael@428 | 70 | - -- # (first install time) to be within specified begin |
michael@428 | 71 | - -- # and end date |
michael@428 | 72 | - -- |
michael@428 | 73 | - -- | "Assertion-FromSourceOnTarget:" yes-no |
michael@428 | 74 | - -- # require either (if "yes") that all package |
michael@428 | 75 | - -- # %{BUILDHOST} are equal the host name or (if "no") |
michael@428 | 76 | - -- # that all package %{BUILDHOST} are not equal the host |
michael@428 | 77 | - -- # name |
michael@428 | 78 | - -- |
michael@428 | 79 | - -- | "Assertion-PackageNames:" |
michael@428 | 80 | - -- ("!"?.mode-regex.":"."!"?.package-regex)+ |
michael@428 | 81 | - -- # require all package %{NAME} to (not) match the |
michael@428 | 82 | - -- # specified regex while the current RPM run-time mode |
michael@428 | 83 | - -- # has to (not) match the specified regex. RPM run-time |
michael@428 | 84 | - -- # modes are: query, verify, checksig, resign, install, |
michael@428 | 85 | - -- # erase, build rebuild, recompile, tarbuild, initdb, |
michael@428 | 86 | - -- # rebuilddb and verifydb. |
michael@428 | 87 | - -- |
michael@428 | 88 | - -- | "Assertion-PackageReleaseAge:" |
michael@428 | 89 | - -- percent.":".duration.":".dist-regex ((package-name|"*").":".release)+ |
michael@428 | 90 | - -- # require that for at least the specified amount (in |
michael@428 | 91 | - -- # percent) of packages, which %{DISTRIBUTION} matches |
michael@428 | 92 | - -- # the specified regex, the %{RELEASE} is at least as |
michael@428 | 93 | - -- # old as the specified release or at least not older |
michael@428 | 94 | - -- # than the specified duration. |
michael@428 | 95 | - -- |
michael@428 | 96 | - -- | "Assertion-Expression:" expression |
michael@428 | 97 | - -- # evaluates the Lua boolean expression after expanding |
michael@428 | 98 | - -- # RPM macros %{VARNAME} and expanding the construct |
michael@428 | 99 | - -- # "<string>" ~~ /<regex>/ into the corresponding PCRE |
michael@428 | 100 | - -- # based regular expression match. |
michael@428 | 101 | - -- |
michael@428 | 102 | - -- version ::= /^\d+\.\d+\.\d+$/ |
michael@428 | 103 | - -- yes-no ::= /^yes|no$/ |
michael@428 | 104 | - -- url ::= /^https?:\/\/.+$/ |
michael@428 | 105 | - -- path ::= /^\/.+$/ |
michael@428 | 106 | - -- user ::= /^[a-z][a-zA-Z0-9_]*$/ |
michael@428 | 107 | - -- group ::= /^[a-z][a-zA-Z0-9_]*$/ |
michael@428 | 108 | - -- domain ::= /^(?:[^.]+\.)+[^.]+$/ |
michael@428 | 109 | - -- mode-regex ::= /^.+$/ |
michael@428 | 110 | - -- package-regex ::= /^.+$/ |
michael@428 | 111 | - -- package-name ::= /^[a-z][a-zA-Z0-9-]*$/ |
michael@428 | 112 | - -- percent ::= /^\d+%$/ |
michael@428 | 113 | - -- duration ::= /^\d+[smhdw]?$/ |
michael@428 | 114 | - -- release ::= /^\d{8}$/ |
michael@428 | 115 | - -- iso-date ::= /^\d{4}-\d{2}-\d{2}$/ |
michael@428 | 116 | - -- expression ::= /^.+$/ |
michael@428 | 117 | |
michael@428 | 118 | - -- integrity processor version |
michael@428 | 119 | integrity.version = "1.0.0" |
michael@428 | 120 | |
michael@428 | 121 | - -- integrity processor validation callback function |
michael@428 | 122 | function integrity.validate(ctx, cfg) |
michael@428 | 123 | integrity.util.debug(1, "OpenPKG run-time license integrity validation") |
michael@428 | 124 | integrity.util.debug(4, function (ctx) return "dump: ctx = " .. util.dump(ctx) end, ctx) |
michael@428 | 125 | integrity.util.debug(4, function (cfg) return "dump: cfg = " .. util.dump(cfg) end, cfg) |
michael@428 | 126 | |
michael@428 | 127 | -- process "Assertion-OnlineApproval" constraint |
michael@428 | 128 | if os.getenv("OPENPKG_LICENSE_EXCEPTION") ~= nil then |
michael@428 | 129 | -- support explicitly requested license exception |
michael@428 | 130 | cfg["Assertion-OnlineApproval"] = "http://openpkg.com/go/framework-license-exception" |
michael@428 | 131 | end |
michael@428 | 132 | if cfg["Assertion-OnlineApproval"] ~= nil then |
michael@428 | 133 | integrity.util.debug(2, "checking: Assertion-OnlineApproval: \"%s\"", cfg["Assertion-OnlineApproval"]) |
michael@428 | 134 | local uuids = integrity.util.uuids() |
michael@428 | 135 | if uuids["UUID_REGISTRY"] == "" then |
michael@428 | 136 | uuids["UUID_REGISTRY"] = "unknown" |
michael@428 | 137 | end |
michael@428 | 138 | if uuids["UUID_INSTANCE"] == "" then |
michael@428 | 139 | uuids["UUID_INSTANCE"] = "unknown" |
michael@428 | 140 | end |
michael@428 | 141 | if uuids["UUID_PLATFORM"] == "" then |
michael@428 | 142 | uuids["UUID_PLATFORM"] = "unknown" |
michael@428 | 143 | end |
michael@428 | 144 | local request = cfg["Assertion-OnlineApproval"] |
michael@428 | 145 | request = request .. "?UUID_REGISTRY=" .. uuids["UUID_REGISTRY"] |
michael@428 | 146 | request = request .. "&UUID_INSTANCE=" .. uuids["UUID_INSTANCE"] |
michael@428 | 147 | request = request .. "&UUID_PLATFORM=" .. uuids["UUID_PLATFORM"] |
michael@428 | 148 | integrity.util.debug(3, "info: remote request \"%s\"", request) |
michael@428 | 149 | local response = rpm.expand("%(%{l_prefix}/bin/openpkg curl -s -L -R '" .. request .. "')") |
michael@428 | 150 | integrity.util.debug(3, "info: remote response \"%s\"", response) |
michael@428 | 151 | if util.rmatch(response, "(?s)^\\s*OK\\s*$") then |
michael@428 | 152 | -- approved |
michael@428 | 153 | if os.getenv("OPENPKG_LICENSE_EXCEPTION") ~= nil then |
michael@428 | 154 | -- support explicitly requested license exception |
michael@428 | 155 | cfg["Assertion-ErrorToWarning"] = "yes" |
michael@428 | 156 | end |
michael@428 | 157 | else |
michael@428 | 158 | -- rejected |
michael@428 | 159 | cfg["Assertion-ErrorToWarning"] = "no" |
michael@428 | 160 | return integrity.util.error(ctx, cfg, |
michael@428 | 161 | "license requires online approval but we failed to get " .. |
michael@428 | 162 | "an \"OK\" response from the online service") |
michael@428 | 163 | end |
michael@428 | 164 | end |
michael@428 | 165 | |
michael@428 | 166 | -- process "Assertion-MinProcVersion" constraint |
michael@428 | 167 | integrity.util.debug(2, "checking: Assertion-MinProcVersion: \"%s\"", cfg["Assertion-MinProcVersion"]) |
michael@428 | 168 | if cfg["Assertion-MinProcVersion"] == nil then |
michael@428 | 169 | return integrity.util.error(ctx, cfg, |
michael@428 | 170 | "license configuration is missing required \"Assertion-MinProcVersion\" parameter") |
michael@428 | 171 | end |
michael@428 | 172 | integrity.util.debug(3, "require: %s <= %s", cfg["Assertion-MinProcVersion"], integrity.version) |
michael@428 | 173 | if rpm.vercmp(cfg["Assertion-MinProcVersion"], integrity.version) > 0 then |
michael@428 | 174 | return integrity.util.error(ctx, cfg, |
michael@428 | 175 | "license configuration requires a license processor of " .. |
michael@428 | 176 | "at least version \"" .. cfg["Assertion-MinProcVersion"] .. "\"") |
michael@428 | 177 | end |
michael@428 | 178 | |
michael@428 | 179 | -- process "Assertion-OnlineReporting" constraint |
michael@428 | 180 | if cfg["Assertion-OnlineReporting"] ~= nil then |
michael@428 | 181 | integrity.util.debug(2, "checking: Assertion-OnlineReporting: \"%s\"", cfg["Assertion-OnlineReporting"]) |
michael@428 | 182 | local uuids = integrity.util.uuids() |
michael@428 | 183 | if uuids["UUID_REGISTRY"] == "" then |
michael@428 | 184 | uuids["UUID_REGISTRY"] = "unknown" |
michael@428 | 185 | end |
michael@428 | 186 | if uuids["UUID_INSTANCE"] == "" then |
michael@428 | 187 | uuids["UUID_INSTANCE"] = "unknown" |
michael@428 | 188 | end |
michael@428 | 189 | if uuids["UUID_PLATFORM"] == "" then |
michael@428 | 190 | uuids["UUID_PLATFORM"] = "unknown" |
michael@428 | 191 | end |
michael@428 | 192 | local request = cfg["Assertion-OnlineReporting"] |
michael@428 | 193 | request = request .. "?UUID_REGISTRY=" .. uuids["UUID_REGISTRY"] |
michael@428 | 194 | request = request .. "&UUID_INSTANCE=" .. uuids["UUID_INSTANCE"] |
michael@428 | 195 | request = request .. "&UUID_PLATFORM=" .. uuids["UUID_PLATFORM"] |
michael@428 | 196 | integrity.util.debug(3, "info: remote request \"%s\"", request) |
michael@428 | 197 | rpm.expand("%(nohup %{l_prefix}/bin/openpkg curl -s -L -R '" .. request .. "' >/dev/null 2>&1 &)") |
michael@428 | 198 | integrity.util.debug(3, "response: (ignored, because asynchronous operation)") |
michael@428 | 199 | end |
michael@428 | 200 | |
michael@428 | 201 | -- process "Assertion-Prefix" constraint |
michael@428 | 202 | if cfg["Assertion-Prefix"] ~= nil then |
michael@428 | 203 | integrity.util.debug(2, "checking: Assertion-Prefix: \"%s\"", cfg["Assertion-Prefix"]) |
michael@428 | 204 | local prefix = rpm.expand("%{l_prefix}") |
michael@428 | 205 | integrity.util.debug(3, "require: \"%s\" == \"%s\"", cfg["Assertion-Prefix"], prefix) |
michael@428 | 206 | if cfg["Assertion-Prefix"] ~= prefix then |
michael@428 | 207 | return integrity.util.error(ctx, cfg, |
michael@428 | 208 | "instance prefix \"" .. prefix .. "\" " .. |
michael@428 | 209 | "does not match value \"" .. cfg["Assertion-Prefix"] .. "\" of " .. |
michael@428 | 210 | "license configuration parameter \"Assertion-Prefix\"") |
michael@428 | 211 | end |
michael@428 | 212 | end |
michael@428 | 213 | |
michael@428 | 214 | -- process "Assertion-User" constraint |
michael@428 | 215 | if cfg["Assertion-User"] ~= nil then |
michael@428 | 216 | integrity.util.debug(2, "checking: Assertion-User: \"%s\"", cfg["Assertion-User"]) |
michael@428 | 217 | local user = rpm.expand("%{l_musr}") |
michael@428 | 218 | integrity.util.debug(3, "require: \"%s\" == \"%s\"", cfg["Assertion-User"], user) |
michael@428 | 219 | if cfg["Assertion-User"] ~= user then |
michael@428 | 220 | return integrity.util.error(ctx, cfg, |
michael@428 | 221 | "instance management user \"" .. user .. "\" " .. |
michael@428 | 222 | "does not match value \"" .. cfg["Assertion-User"] .. "\" of " .. |
michael@428 | 223 | "license configuration parameter \"Assertion-User\"") |
michael@428 | 224 | end |
michael@428 | 225 | end |
michael@428 | 226 | |
michael@428 | 227 | -- process "Assertion-Group" constraint |
michael@428 | 228 | if cfg["Assertion-Group"] ~= nil then |
michael@428 | 229 | integrity.util.debug(2, "checking: Assertion-Group: \"%s\"", cfg["Assertion-Group"]) |
michael@428 | 230 | local group = rpm.expand("%{l_mgrp}") |
michael@428 | 231 | integrity.util.debug(3, "require: \"%s\" == \"%s\"", cfg["Assertion-Group"], group) |
michael@428 | 232 | if cfg["Assertion-Group"] ~= group then |
michael@428 | 233 | return integrity.util.error(ctx, cfg, |
michael@428 | 234 | "instance management group \"" .. group .. "\" " .. |
michael@428 | 235 | "does not match value \"" .. cfg["Assertion-Group"] .. "\" of " .. |
michael@428 | 236 | "license configuration parameter \"Assertion-Group\"") |
michael@428 | 237 | end |
michael@428 | 238 | end |
michael@428 | 239 | |
michael@428 | 240 | -- process "Assertion-Domain" constraint |
michael@428 | 241 | if cfg["Assertion-Domain"] ~= nil then |
michael@428 | 242 | integrity.util.debug(2, "checking: Assertion-Domain: \"%s\"", cfg["Assertion-Domain"]) |
michael@428 | 243 | local domain = rpm.expand("%(%{l_shtool} echo -n -e '%d')") |
michael@428 | 244 | integrity.util.debug(3, "require: \"%s\" ~~ /(?s)^.*%s$/", domain, cfg["Assertion-Domain"]) |
michael@428 | 245 | local s, _, m = util.rmatch(domain, "(?s)^.*" .. cfg["Assertion-Domain"] .. "$") |
michael@428 | 246 | if s == nil then |
michael@428 | 247 | return integrity.util.error(ctx, cfg, |
michael@428 | 248 | "host domain \"" .. domain .. "\" " .. |
michael@428 | 249 | "does not end in pattern \"" .. cfg["Assertion-Domain"] .. "\") " .. |
michael@428 | 250 | "of license configuration parameter \"Assertion-Domain\"") |
michael@428 | 251 | end |
michael@428 | 252 | end |
michael@428 | 253 | |
michael@428 | 254 | -- process "Assertion-LifeTime" constraint |
michael@428 | 255 | if cfg["Assertion-LifeTime"] ~= nil then |
michael@428 | 256 | integrity.util.debug(2, "checking: Assertion-LifeTime: \"%s\"", cfg["Assertion-LifeTime"]) |
michael@428 | 257 | |
michael@428 | 258 | -- determine lifetime begin and end |
michael@428 | 259 | local lifetime = cfg["Assertion-LifeTime"] |
michael@428 | 260 | local s, _, m = util.rmatch(lifetime, "^(?s)(\\d{4})-(\\d{2})-(\\d{2})\\s*:\\s*(\\d{4})-(\\d{2})-(\\d{2})$") |
michael@428 | 261 | if s == nil then |
michael@428 | 262 | return integrity.util.error(ctx, cfg, |
michael@428 | 263 | "failed to extract time information from " .. |
michael@428 | 264 | "license configuration parameter \"Assertion-LifeTime\"") |
michael@428 | 265 | end |
michael@428 | 266 | local lifetime_begin = os.time({ |
michael@428 | 267 | year = tonumber(m[1]), |
michael@428 | 268 | month = tonumber(m[2]), |
michael@428 | 269 | day = tonumber(m[3]), |
michael@428 | 270 | hour = 0, |
michael@428 | 271 | min = 0, |
michael@428 | 272 | sec = 0 |
michael@428 | 273 | }) |
michael@428 | 274 | local lifetime_end = os.time({ |
michael@428 | 275 | year = tonumber(m[4]), |
michael@428 | 276 | month = tonumber(m[5]), |
michael@428 | 277 | day = tonumber(m[6]), |
michael@428 | 278 | hour = 23, |
michael@428 | 279 | min = 59, |
michael@428 | 280 | sec = 59 |
michael@428 | 281 | }) |
michael@428 | 282 | |
michael@428 | 283 | -- check whether current run-time is within lifetime |
michael@428 | 284 | local t_now = os.time() |
michael@428 | 285 | integrity.util.debug(3, "require: %d <= %d <= %d", lifetime_begin, t_now, lifetime_end) |
michael@428 | 286 | if not (lifetime_begin <= t_now and t_now <= lifetime_end) then |
michael@428 | 287 | return integrity.util.error(ctx, cfg, |
michael@428 | 288 | "current time \"" .. os.date("!%Y-%m-%d %H:%M:%S UTC", t_now) .. "\" " .. |
michael@428 | 289 | "is not within the timerange \"" .. cfg["Assertion-LifeTime"] .. "\" " .. |
michael@428 | 290 | "of license configuration parameter \"Assertion-LifeTime\"") |
michael@428 | 291 | end |
michael@428 | 292 | end |
michael@428 | 293 | |
michael@428 | 294 | -- process "Assertion-GrantTime" constraint |
michael@428 | 295 | if cfg["Assertion-GrantTime"] ~= nil then |
michael@428 | 296 | integrity.util.debug(2, "checking: Assertion-GrantTime: \"%s\"", cfg["Assertion-GrantTime"]) |
michael@428 | 297 | |
michael@428 | 298 | -- determine granttime begin and end |
michael@428 | 299 | local granttime = cfg["Assertion-GrantTime"] |
michael@428 | 300 | local s, _, m = util.rmatch(granttime, "^(?s)(\\d{4})-(\\d{2})-(\\d{2})\\s*:\\s*(\\d{4})-(\\d{2})-(\\d{2})$") |
michael@428 | 301 | if s == nil then |
michael@428 | 302 | return integrity.util.error(ctx, cfg, |
michael@428 | 303 | "failed to extract time information from " .. |
michael@428 | 304 | "license configuration parameter \"Assertion-GrantTime\"") |
michael@428 | 305 | end |
michael@428 | 306 | local granttime_begin = os.time({ |
michael@428 | 307 | year = tonumber(m[1]), |
michael@428 | 308 | month = tonumber(m[2]), |
michael@428 | 309 | day = tonumber(m[3]), |
michael@428 | 310 | hour = 0, |
michael@428 | 311 | min = 0, |
michael@428 | 312 | sec = 0 |
michael@428 | 313 | }) |
michael@428 | 314 | local granttime_end = os.time({ |
michael@428 | 315 | year = tonumber(m[4]), |
michael@428 | 316 | month = tonumber(m[5]), |
michael@428 | 317 | day = tonumber(m[6]), |
michael@428 | 318 | hour = 23, |
michael@428 | 319 | min = 59, |
michael@428 | 320 | sec = 59 |
michael@428 | 321 | }) |
michael@428 | 322 | |
michael@428 | 323 | -- determine OpenPKG Framework release time |
michael@428 | 324 | -- (allow openpkg.spec:%pre to override with a higher value for pre-checking) |
michael@428 | 325 | local t_release = 0 |
michael@428 | 326 | local result = {} |
michael@428 | 327 | for _, line in ipairs(rpm.query("Q:%{RELEASE}", false, "openpkg")) do |
michael@428 | 328 | local s, _, m = util.rmatch(line, "(?s)^Q:(.+)$") |
michael@428 | 329 | if s ~= nil then |
michael@428 | 330 | table.insert(result, m[1]) |
michael@428 | 331 | end |
michael@428 | 332 | end |
michael@428 | 333 | if result[1] ~= nil then |
michael@428 | 334 | local s, _, m = util.rmatch(result[1], "^(?s)(\\d{4})(\\d{2})(\\d{2})$") |
michael@428 | 335 | if s ~= nil then |
michael@428 | 336 | t_release = os.time({ |
michael@428 | 337 | year = tonumber(m[1]), |
michael@428 | 338 | month = tonumber(m[2]), |
michael@428 | 339 | day = tonumber(m[3]), |
michael@428 | 340 | hour = 0, |
michael@428 | 341 | min = 0, |
michael@428 | 342 | sec = 0 |
michael@428 | 343 | }) |
michael@428 | 344 | end |
michael@428 | 345 | end |
michael@428 | 346 | if t_release == 0 then |
michael@428 | 347 | return integrity.util.error(ctx, cfg, |
michael@428 | 348 | "failed to determine OpenPKG Framework release time") |
michael@428 | 349 | end |
michael@428 | 350 | local override = os.getenv("OPENPKG_FRAMEWORK_RELEASE") |
michael@428 | 351 | if override ~= nil then |
michael@428 | 352 | local s, _, m = util.rmatch(override, "^(?s)(\\d{4})(\\d{2})(\\d{2})$") |
michael@428 | 353 | if s ~= nil then |
michael@428 | 354 | local t_override = os.time({ |
michael@428 | 355 | year = tonumber(m[1]), |
michael@428 | 356 | month = tonumber(m[2]), |
michael@428 | 357 | day = tonumber(m[3]), |
michael@428 | 358 | hour = 0, |
michael@428 | 359 | min = 0, |
michael@428 | 360 | sec = 0 |
michael@428 | 361 | }) |
michael@428 | 362 | if t_release < t_override then |
michael@428 | 363 | t_release = t_override |
michael@428 | 364 | end |
michael@428 | 365 | end |
michael@428 | 366 | end |
michael@428 | 367 | |
michael@428 | 368 | -- check whether current OpenPKG Framework release time is within granttime |
michael@428 | 369 | integrity.util.debug(3, "require: %d <= %d <= %d", granttime_begin, t_release, granttime_end) |
michael@428 | 370 | if not (granttime_begin <= t_release and t_release <= granttime_end) then |
michael@428 | 371 | return integrity.util.error(ctx, cfg, |
michael@428 | 372 | "current OpenPKG Framework release time \"" .. os.date("%Y-%m-%d", t_release) .. "\" " .. |
michael@428 | 373 | "is not within the timerange \"" .. cfg["Assertion-GrantTime"] .. "\" " .. |
michael@428 | 374 | "of license configuration parameter \"Assertion-GrantTime\"") |
michael@428 | 375 | end |
michael@428 | 376 | end |
michael@428 | 377 | |
michael@428 | 378 | -- process "Assertion-InstanceAge" constraint |
michael@428 | 379 | if cfg["Assertion-InstanceAge"] ~= nil then |
michael@428 | 380 | integrity.util.debug(2, "checking: Assertion-InstanceAge: \"%s\"", cfg["Assertion-InstanceAge"]) |
michael@428 | 381 | |
michael@428 | 382 | -- determine maximum instance age in seconds |
michael@428 | 383 | local t_diff_max = cfg["Assertion-InstanceAge"] |
michael@428 | 384 | t_diff_max = 0 + util.rsubst(t_diff_max, "^(\\d+)([smhdw])$", function (t, unit) |
michael@428 | 385 | if unit == "s" then t = t * 1 |
michael@428 | 386 | elseif unit == "m" then t = t * 60 |
michael@428 | 387 | elseif unit == "h" then t = t * 60 * 60 |
michael@428 | 388 | elseif unit == "d" then t = t * 60 * 60 * 24 |
michael@428 | 389 | elseif unit == "w" then t = t * 60 * 60 * 24 * 7 |
michael@428 | 390 | end |
michael@428 | 391 | return t |
michael@428 | 392 | end) |
michael@428 | 393 | |
michael@428 | 394 | -- approach 1: determine install time via timestamp of UUID_REGISTRY |
michael@428 | 395 | local uuids = integrity.util.uuids() |
michael@428 | 396 | if uuids["UUID_REGISTRY"] == "" then |
michael@428 | 397 | return integrity.util.error(ctx, cfg, |
michael@428 | 398 | "failed to load UUID_REGISTRY") |
michael@428 | 399 | end |
michael@428 | 400 | txt = uuid.describe(uuids["UUID_REGISTRY"]) |
michael@428 | 401 | if txt == nil then |
michael@428 | 402 | return integrity.util.error(ctx, cfg, |
michael@428 | 403 | "failed to parse extracted UUID_REGISTRY string \"" .. uuids["UUID_REGISTRY"] .. "\" as an UUID") |
michael@428 | 404 | end |
michael@428 | 405 | local s, _, m = util.rmatch(txt, "(?s)^.*time:\\s+(\\d{4})-(\\d{2})-(\\d{2})\\s+(\\d{2}):(\\d{2}):(\\d{2}).*$") |
michael@428 | 406 | if s == nil then |
michael@428 | 407 | return integrity.util.error(ctx, cfg, |
michael@428 | 408 | "failed to extract timestamp from UUID_REGISTRY \"" .. uuids["UUID_REGISTRY"] .. "\"") |
michael@428 | 409 | end |
michael@428 | 410 | local t_install = os.time({ |
michael@428 | 411 | year = tonumber(m[1]), |
michael@428 | 412 | month = tonumber(m[2]), |
michael@428 | 413 | day = tonumber(m[3]), |
michael@428 | 414 | hour = tonumber(m[4]), |
michael@428 | 415 | min = tonumber(m[5]), |
michael@428 | 416 | sec = tonumber(m[6]) |
michael@428 | 417 | }) |
michael@428 | 418 | |
michael@428 | 419 | -- approach 2: determine install time via first install time of "openpkg" package |
michael@428 | 420 | local result = {} |
michael@428 | 421 | for _, line in ipairs(rpm.query( |
michael@428 | 422 | "Q:%|ORIGINTIME?{" .. |
michael@428 | 423 | "%{ORIGINTIME}" .. -- regular case: RPM 5 installed/updated with RPM 5 |
michael@428 | 424 | "}:{" .. |
michael@428 | 425 | "%|INSTALLTIME?{" .. |
michael@428 | 426 | "%{INSTALLTIME}" .. -- special case: RPM 5 installed initially with RPM 4 |
michael@428 | 427 | "}:{" .. |
michael@428 | 428 | "}|" .. |
michael@428 | 429 | "}|", false, "openpkg" |
michael@428 | 430 | )) do |
michael@428 | 431 | local s, _, m = util.rmatch(line, "(?s)^Q:(.+)$") |
michael@428 | 432 | if s ~= nil then |
michael@428 | 433 | table.insert(result, m[1]) |
michael@428 | 434 | end |
michael@428 | 435 | end |
michael@428 | 436 | if result[1] ~= nil then |
michael@428 | 437 | local n = tonumber(result[1]) |
michael@428 | 438 | if n > 0 then |
michael@428 | 439 | t_install = n |
michael@428 | 440 | end |
michael@428 | 441 | end |
michael@428 | 442 | |
michael@428 | 443 | -- check time difference |
michael@428 | 444 | local t_now = os.time() |
michael@428 | 445 | local t_diff = os.difftime(t_now, t_install) |
michael@428 | 446 | integrity.util.debug(3, "calc: %d - %d = %d", t_now, t_install, t_diff) |
michael@428 | 447 | if t_diff < 0 then |
michael@428 | 448 | return integrity.util.error(ctx, cfg, |
michael@428 | 449 | "current system time \"" .. t_now .. "\" is lower than " .. |
michael@428 | 450 | "instance installation time \"" .. t_install .. "\"") |
michael@428 | 451 | end |
michael@428 | 452 | integrity.util.debug(3, "require: %d <= %d", t_diff, t_diff_max) |
michael@428 | 453 | if t_diff > t_diff_max then |
michael@428 | 454 | return integrity.util.error(ctx, cfg, |
michael@428 | 455 | "instance age \"" .. t_diff .. "\" " .. |
michael@428 | 456 | "is greater than value \"" .. t_diff_max .. "\" (\"" .. cfg["Assertion-InstanceAge"] .. "\") " .. |
michael@428 | 457 | "of license configuration parameter \"Assertion-InstanceAge\"") |
michael@428 | 458 | end |
michael@428 | 459 | end |
michael@428 | 460 | |
michael@428 | 461 | -- process "Assertion-FromSourceOnTarget" constraint |
michael@428 | 462 | if cfg["Assertion-FromSourceOnTarget"] ~= nil then |
michael@428 | 463 | integrity.util.debug(2, "checking: Assertion-FromSourceOnTarget: \"%s\"", cfg["Assertion-FromSourceOnTarget"]) |
michael@428 | 464 | local hostname = rpm.hostname() |
michael@428 | 465 | for _, line in ipairs(rpm.query("Q:%{NAME}:%{BUILDHOST}", true, "*")) do |
michael@428 | 466 | local s, _, m = util.rmatch(line, "(?s)^Q:([^:]+):(.+)$") |
michael@428 | 467 | if s ~= nil then |
michael@428 | 468 | local name = m[1] |
michael@428 | 469 | local buildhost = m[2] |
michael@428 | 470 | integrity.util.debug(4, "info: name \"%s\", buildhost \"%s\"", name, buildhost) |
michael@428 | 471 | if not util.rmatch(name, "(?s)^gpg-.+$") and buildhost ~= "localhost" then |
michael@428 | 472 | if cfg["Assertion-FromSourceOnTarget"] == "yes" and buildhost ~= hostname then |
michael@428 | 473 | return integrity.util.error(ctx, cfg, |
michael@428 | 474 | "license-required \"build from source on target system only\" situation not met because " .. |
michael@428 | 475 | "package build host \"" .. buildhost .. "\" is not(!) equal to the package install host \"" .. hostname .. "\".") |
michael@428 | 476 | end |
michael@428 | 477 | if cfg["Assertion-FromSourceOnTarget"] == "no" and buildhost == hostname then |
michael@428 | 478 | return integrity.util.error(ctx, cfg, |
michael@428 | 479 | "license-required \"build binaries on separate build-host only\" situation not met because " .. |
michael@428 | 480 | "package build host \"" .. buildhost .. "\" is equal to the package install host \"" .. hostname .. "\".") |
michael@428 | 481 | end |
michael@428 | 482 | end |
michael@428 | 483 | end |
michael@428 | 484 | end |
michael@428 | 485 | end |
michael@428 | 486 | |
michael@428 | 487 | -- process "Assertion-PackageNames" constraints |
michael@428 | 488 | if cfg["Assertion-PackageNames"] ~= nil then |
michael@428 | 489 | integrity.util.debug(2, "checking: Assertion-PackageNames: \"%s\"", cfg["Assertion-PackageNames"]) |
michael@428 | 490 | |
michael@428 | 491 | -- query RPMDB for names of all installed packages |
michael@428 | 492 | local packages = {} |
michael@428 | 493 | for _, line in ipairs(rpm.query("Q:%{NAME}", true, "*")) do |
michael@428 | 494 | local s, _, m = util.rmatch(line, "(?s)^Q:(.+)$") |
michael@428 | 495 | if s ~= nil then |
michael@428 | 496 | table.insert(packages, m[1]) |
michael@428 | 497 | end |
michael@428 | 498 | end |
michael@428 | 499 | |
michael@428 | 500 | -- iterate over all constraints |
michael@428 | 501 | for _, constraint in |
michael@428 | 502 | ipairs( |
michael@428 | 503 | util.rsplit( |
michael@428 | 504 | util.rsubst( |
michael@428 | 505 | cfg["Assertion-PackageNames"], |
michael@428 | 506 | "(?s)^\\s*(.+?)\\s*$", "%1" |
michael@428 | 507 | ), |
michael@428 | 508 | "(?s)\\s+" |
michael@428 | 509 | ) |
michael@428 | 510 | ) do |
michael@428 | 511 | -- parse constraint |
michael@428 | 512 | local s, _, m = util.rmatch(constraint, "(?s)^(!?)([^:]+):(!?)(.+)$") |
michael@428 | 513 | if s == nil then |
michael@428 | 514 | return integrity.util.error(ctx, cfg, |
michael@428 | 515 | "invalid syntax in license configuration \"Assertion-PackageNames\" " .. |
michael@428 | 516 | "parameter: \"" .. constraint .. "\"") |
michael@428 | 517 | end |
michael@428 | 518 | local mode_negate = m[1] ~= "" |
michael@428 | 519 | local mode_regex = m[2] |
michael@428 | 520 | local package_negate = m[3] ~= "" |
michael@428 | 521 | local package_regex = m[4] |
michael@428 | 522 | -- apply the mode filter |
michael@428 | 523 | local mode_matches, _, _ = util.rmatch(ctx.rpm.mode, mode_regex); |
michael@428 | 524 | if (not mode_negate and mode_matches ~= nil) |
michael@428 | 525 | or ( mode_negate and mode_matches == nil) then |
michael@428 | 526 | -- apply the package filter to names of all installed packages |
michael@428 | 527 | for _, package in ipairs(packages) do |
michael@428 | 528 | if package_negate then |
michael@428 | 529 | integrity.util.debug(3, "require: \"%s\" !~ /%s/", package, package_regex) |
michael@428 | 530 | else |
michael@428 | 531 | integrity.util.debug(3, "require: \"%s\" ~~ /%s/", package, package_regex) |
michael@428 | 532 | end |
michael@428 | 533 | local package_matches, _, _ = util.rmatch(package, package_regex) |
michael@428 | 534 | if not ( (not package_negate and package_matches ~= nil) |
michael@428 | 535 | or ( package_negate and package_matches == nil)) then |
michael@428 | 536 | -- indicate integrity validation error |
michael@428 | 537 | return integrity.util.error(ctx, cfg, |
michael@428 | 538 | "installed package \"" .. package .. "\" " .. |
michael@428 | 539 | "under RPM run-time mode \"" .. ctx.rpm.mode .. "\" " .. |
michael@428 | 540 | "not covered by pattern \"" .. package_regex .. "\" " .. |
michael@428 | 541 | "of license configuration parameter \"Assertion-PackageNames\"") |
michael@428 | 542 | end |
michael@428 | 543 | end |
michael@428 | 544 | end |
michael@428 | 545 | end |
michael@428 | 546 | end |
michael@428 | 547 | |
michael@428 | 548 | -- process "Assertion-PackageReleaseAge" |
michael@428 | 549 | if cfg["Assertion-PackageReleaseAge"] ~= nil then |
michael@428 | 550 | integrity.util.debug(2, "checking: Assertion-PackageReleaseAge: \"%s[...]\"", string.sub(cfg["Assertion-PackageReleaseAge"], 1, 20)) |
michael@428 | 551 | |
michael@428 | 552 | -- parse constraint |
michael@428 | 553 | local constraint = cfg["Assertion-PackageReleaseAge"] |
michael@428 | 554 | local s, _, m = util.rmatch(constraint, "(?s)^([^:]+)%:([^:]+):([^\\s]+)\\s+(.+)$") |
michael@428 | 555 | if s == nil then |
michael@428 | 556 | return integrity.util.error(ctx, cfg, |
michael@428 | 557 | "invalid syntax in license configuration \"Assertion-PackageReleaseAge\" parameter") |
michael@428 | 558 | end |
michael@428 | 559 | local percent = m[1] / 100 |
michael@428 | 560 | local offset = m[2] |
michael@428 | 561 | local distregex = m[3] |
michael@428 | 562 | local spec = m[4] |
michael@428 | 563 | |
michael@428 | 564 | -- determine maximum release time difference (in seconds) |
michael@428 | 565 | local t_diff_max = 0 + util.rsubst(offset, "^(\\d+)([smhdw])$", function (t, unit) |
michael@428 | 566 | if unit == "s" then t = t * 1 |
michael@428 | 567 | elseif unit == "m" then t = t * 60 |
michael@428 | 568 | elseif unit == "h" then t = t * 60 * 60 |
michael@428 | 569 | elseif unit == "d" then t = t * 60 * 60 * 24 |
michael@428 | 570 | elseif unit == "w" then t = t * 60 * 60 * 24 * 7 |
michael@428 | 571 | end |
michael@428 | 572 | return t |
michael@428 | 573 | end) |
michael@428 | 574 | |
michael@428 | 575 | -- iterate over all package specifications to build release map |
michael@428 | 576 | local releases = {} |
michael@428 | 577 | for _, constraint in |
michael@428 | 578 | ipairs( |
michael@428 | 579 | util.rsplit( |
michael@428 | 580 | util.rsubst( |
michael@428 | 581 | spec, |
michael@428 | 582 | "(?s)^\\s*(.+?)\\s*$", "%1" |
michael@428 | 583 | ), |
michael@428 | 584 | "(?s)\\s+" |
michael@428 | 585 | ) |
michael@428 | 586 | ) do |
michael@428 | 587 | |
michael@428 | 588 | -- parse specification into package name and release constraint |
michael@428 | 589 | local s, _, m = util.rmatch(constraint, "(?s)^([^:]+):(.+)$") |
michael@428 | 590 | if s == nil then |
michael@428 | 591 | return integrity.util.error(ctx, cfg, |
michael@428 | 592 | "invalid syntax in license configuration \"Assertion-PackageReleaseAge\" " .. |
michael@428 | 593 | "parameter: \"" .. constraint .. "\"") |
michael@428 | 594 | end |
michael@428 | 595 | |
michael@428 | 596 | -- store result into release map |
michael@428 | 597 | releases[m[1]] = m[2] |
michael@428 | 598 | end |
michael@428 | 599 | |
michael@428 | 600 | -- query RPMDB for releases of all installed packages and decide |
michael@428 | 601 | -- whether the release time is inside or outside our constraint window |
michael@428 | 602 | local release_window_inside = 0 |
michael@428 | 603 | local release_window_outside = 0 |
michael@428 | 604 | local release_window_foreign = 0 |
michael@428 | 605 | local release_window_unknown = 0 |
michael@428 | 606 | for _, line in ipairs(rpm.query("Q:%{NAME}:%{RELEASE}:%{DISTRIBUTION}", true, "*")) do |
michael@428 | 607 | local s, _, m = util.rmatch(line, "(?s)^Q:([^:]+):(\\d\\d\\d\\d)(\\d\\d)(\\d\\d):(.+)$") |
michael@428 | 608 | if s ~= nil then |
michael@428 | 609 | -- parse query results |
michael@428 | 610 | local name = m[1] |
michael@428 | 611 | local t_release = os.time({ |
michael@428 | 612 | year = tonumber(m[2]), |
michael@428 | 613 | month = tonumber(m[3]), |
michael@428 | 614 | day = tonumber(m[4]), |
michael@428 | 615 | hour = 23, |
michael@428 | 616 | min = 59, |
michael@428 | 617 | sec = 59 |
michael@428 | 618 | }) |
michael@428 | 619 | local dist = m[5] |
michael@428 | 620 | |
michael@428 | 621 | -- only check files of the constrained distribution(s) |
michael@428 | 622 | if util.rmatch(dist, "(?s)" .. distregex) then |
michael@428 | 623 | |
michael@428 | 624 | -- determine minimum release constraint |
michael@428 | 625 | local t_release_min = releases[name] |
michael@428 | 626 | if t_release_min == nil then |
michael@428 | 627 | t_release_min = releases["*"] |
michael@428 | 628 | end |
michael@428 | 629 | if t_release_min == nil then |
michael@428 | 630 | t_release_min = os.time() |
michael@428 | 631 | else |
michael@428 | 632 | local s, _, m = util.rmatch(t_release_min, "^(?s)(\\d{4})(\\d{2})(\\d{2})$") |
michael@428 | 633 | t_release_min = os.time({ |
michael@428 | 634 | year = tonumber(m[1]), |
michael@428 | 635 | month = tonumber(m[2]), |
michael@428 | 636 | day = tonumber(m[3]), |
michael@428 | 637 | hour = 0, |
michael@428 | 638 | min = 0, |
michael@428 | 639 | sec = 0 |
michael@428 | 640 | }) |
michael@428 | 641 | end |
michael@428 | 642 | |
michael@428 | 643 | -- check time difference of package release |
michael@428 | 644 | local t_diff = os.difftime(t_release_min, t_release) |
michael@428 | 645 | integrity.util.debug(4, "calc: %d - %d = %d", t_release_min, t_release, t_diff) |
michael@428 | 646 | integrity.util.debug(4, "require: %d <= 0 or (%d > 0 and %d < %d)", t_diff, t_diff, t_diff, t_diff_max) |
michael@428 | 647 | if t_diff <= 0 or (t_diff > 0 and t_diff < t_diff_max) then |
michael@428 | 648 | release_window_inside = release_window_inside + 1 |
michael@428 | 649 | else |
michael@428 | 650 | release_window_outside = release_window_outside + 1 |
michael@428 | 651 | end |
michael@428 | 652 | else |
michael@428 | 653 | release_window_foreign = release_window_foreign + 1 |
michael@428 | 654 | end |
michael@428 | 655 | else |
michael@428 | 656 | release_window_unknown = release_window_unknown + 1 |
michael@428 | 657 | end |
michael@428 | 658 | end |
michael@428 | 659 | integrity.util.debug(3, "info: inside %d, outside %d, foreign %d, unknown %d", |
michael@428 | 660 | release_window_inside, release_window_outside, release_window_foreign, release_window_unknown) |
michael@428 | 661 | |
michael@428 | 662 | -- check validity of overall constraint |
michael@428 | 663 | local percent_inside = |
michael@428 | 664 | (release_window_inside / (release_window_inside + release_window_outside)) |
michael@428 | 665 | integrity.util.debug(3, "require: %d >= %d", percent_inside, percent) |
michael@428 | 666 | if percent_inside < percent then |
michael@428 | 667 | return integrity.util.error(ctx, cfg, |
michael@428 | 668 | "there are only " .. math.floor(percent_inside * 100) .. "% " .. |
michael@428 | 669 | "packages inside the release date constraint " .. |
michael@428 | 670 | "(expected a minimum of " .. math.floor(percent * 100) .. "%)") |
michael@428 | 671 | end |
michael@428 | 672 | end |
michael@428 | 673 | |
michael@428 | 674 | -- process "Assertion-Expression" constraint |
michael@428 | 675 | if cfg["Assertion-Expression"] ~= nil then |
michael@428 | 676 | integrity.util.debug(2, "checking: Assertion-Expression: \"%s\"", cfg["Assertion-Expression"]) |
michael@428 | 677 | |
michael@428 | 678 | -- expand special consytructs in expression |
michael@428 | 679 | local expr = cfg["Assertion-Expression"] |
michael@428 | 680 | expr = util.rsubst(expr, "(%\{[a-zA-Z_][a-zA-Z0-9_]+\})", function (str) |
michael@428 | 681 | return rpm.expand(str) |
michael@428 | 682 | end) |
michael@428 | 683 | expr = util.rsubst(expr, "\"((?:\\\\.|[^\"])+)\"\\s*~~\\s*/((?:\\\\.|[^/])+)/", function (str, regex) |
michael@428 | 684 | if util.rmatch(str, "(?s)" .. regex) ~= nil then |
michael@428 | 685 | return "true" |
michael@428 | 686 | else |
michael@428 | 687 | return "false" |
michael@428 | 688 | end |
michael@428 | 689 | end) |
michael@428 | 690 | |
michael@428 | 691 | -- evaluate expression |
michael@428 | 692 | integrity.util.debug(3, "evaluate: %s", expr) |
michael@428 | 693 | result = assert(loadstring(expr))() |
michael@428 | 694 | if type(result) ~= "boolean" then |
michael@428 | 695 | result = false |
michael@428 | 696 | end |
michael@428 | 697 | if not result then |
michael@428 | 698 | return integrity.util.error(ctx, cfg, |
michael@428 | 699 | "expression \"" .. cfg["Assertion-Expression"] .. "\" " .. |
michael@428 | 700 | "of license configuration parameter \"Assertion-Expression\"" .. |
michael@428 | 701 | "evaluated to false") |
michael@428 | 702 | end |
michael@428 | 703 | end |
michael@428 | 704 | |
michael@428 | 705 | -- indicate license integrity validation success |
michael@428 | 706 | return "OK" |
michael@428 | 707 | end |
michael@428 | 708 | |
michael@428 | 709 | - -- integrity processor utilities namespace |
michael@428 | 710 | integrity.util = {} |
michael@428 | 711 | |
michael@428 | 712 | - -- write debug information to stderr |
michael@428 | 713 | function integrity.util.debug(level_this, msg, ...) |
michael@428 | 714 | local level_min = os.getenv("OPENPKG_LICENSE_DEBUG") |
michael@428 | 715 | if level_min ~= nil then |
michael@428 | 716 | if type(level_min) == "string" then |
michael@428 | 717 | level_min = tonumber(level_min) |
michael@428 | 718 | end |
michael@428 | 719 | if type(level_min) ~= "number" then |
michael@428 | 720 | level_min = 0 |
michael@428 | 721 | end |
michael@428 | 722 | if level_this <= level_min then |
michael@428 | 723 | local output |
michael@428 | 724 | if type(msg) == "function" then |
michael@428 | 725 | output = msg(...) |
michael@428 | 726 | else |
michael@428 | 727 | output = string.format(msg, ...) |
michael@428 | 728 | end |
michael@428 | 729 | local prefix = "" |
michael@428 | 730 | local i = 1 |
michael@428 | 731 | while (i < level_this) do |
michael@428 | 732 | prefix = prefix .. " " |
michael@428 | 733 | i = i + 1 |
michael@428 | 734 | end |
michael@428 | 735 | io.stderr:write("rpm: DEBUG: " .. prefix .. output .. "\n") |
michael@428 | 736 | end |
michael@428 | 737 | end |
michael@428 | 738 | end |
michael@428 | 739 | |
michael@428 | 740 | - -- load OpenPKG instance UUIDs |
michael@428 | 741 | function integrity.util.uuids() |
michael@428 | 742 | local uuids = { |
michael@428 | 743 | UUID_REGISTRY = "", |
michael@428 | 744 | UUID_INSTANCE = "", |
michael@428 | 745 | UUID_PLATFORM = "" |
michael@428 | 746 | } |
michael@428 | 747 | local filename = rpm.expand("%{l_prefix}/etc/openpkg/uuid") |
michael@428 | 748 | local txt = rpm.slurp(filename) |
michael@428 | 749 | if txt ~= nil then |
michael@428 | 750 | for name, _ in pairs(uuids) do |
michael@428 | 751 | local s, _, m = util.rmatch(txt, "(?s)^.*" .. name .. "=\"([^\"\"]+)\".*$") |
michael@428 | 752 | if s ~= nil then |
michael@428 | 753 | uuids[name] = m[1] |
michael@428 | 754 | end |
michael@428 | 755 | end |
michael@428 | 756 | end |
michael@428 | 757 | return uuids |
michael@428 | 758 | end |
michael@428 | 759 | |
michael@428 | 760 | - -- report validation warning |
michael@428 | 761 | function integrity.util.warning(ctx, cfg, warning) |
michael@428 | 762 | -- return prominent warning message |
michael@428 | 763 | return |
michael@428 | 764 | "WARNING: OpenPKG run-time license check failed -- continue processing\n" .. |
michael@428 | 765 | "+-----------------------------------------------------------------------------+\n" .. |
michael@428 | 766 | "| Attention, the OpenPKG RPM run-time integrity checking facility encountered a\n" .. |
michael@428 | 767 | "| non-fatal problem during license checking, but allows processing to continue.\n" .. |
michael@428 | 768 | "| The particular warning reported by the OpenPKG license processor is:\n" .. |
michael@428 | 769 | "|\n" .. |
michael@428 | 770 | util.textwrap("| ", warning, 60, 70) .. |
michael@428 | 771 | "|\n" .. |
michael@428 | 772 | "| Notice: Operation of the OpenPKG Framework requires a valid license.\n" .. |
michael@428 | 773 | "| Go to http://openpkg.com/go/framework-license for more details, please.\n" .. |
michael@428 | 774 | "+-----------------------------------------------------------------------------+" |
michael@428 | 775 | end |
michael@428 | 776 | |
michael@428 | 777 | - -- report validation error |
michael@428 | 778 | function integrity.util.error(ctx, cfg, error) |
michael@428 | 779 | -- support conversion of errors into warnings |
michael@428 | 780 | if cfg["Assertion-ErrorToWarning"] ~= nil then |
michael@428 | 781 | if cfg["Assertion-ErrorToWarning"] == "yes" then |
michael@428 | 782 | return integrity.util.warning(ctx, cfg, error) |
michael@428 | 783 | end |
michael@428 | 784 | end |
michael@428 | 785 | |
michael@428 | 786 | -- return prominent error message |
michael@428 | 787 | return |
michael@428 | 788 | "ERROR: OpenPKG run-time license check failed -- stopping processing\n" .. |
michael@428 | 789 | "+-----------------------------------------------------------------------------+\n" .. |
michael@428 | 790 | "| Sorry, the OpenPKG RPM run-time integrity checking facility encountered a\n" .. |
michael@428 | 791 | "| fatal problem during license checking and stops processing immediately.\n" .. |
michael@428 | 792 | "| The particular error reported by the OpenPKG license processor is:\n" .. |
michael@428 | 793 | "|\n" .. |
michael@428 | 794 | util.textwrap("| ", error, 60, 70) .. |
michael@428 | 795 | "|\n" .. |
michael@428 | 796 | "| Notice: Operation of the OpenPKG Framework requires a valid license.\n" .. |
michael@428 | 797 | "| Go to http://openpkg.com/go/framework-license for more details, please.\n" .. |
michael@428 | 798 | "| Run \"openpkg man license\" for details about local license management.\n" .. |
michael@428 | 799 | "+-----------------------------------------------------------------------------+" |
michael@428 | 800 | end |
michael@428 | 801 | |
michael@428 | 802 | -----BEGIN PGP SIGNATURE----- |
michael@428 | 803 | Comment: OpenPKG GmbH <openpkg@openpkg.com> |
michael@428 | 804 | |
michael@428 | 805 | iEYEARECAAYFAk8BelcACgkQZwQuyWG3rjTL6QCeLTLVj4PTnd/E7mf+Sv4mgbZj |
michael@428 | 806 | 5J0AoMXrO4EimPSSCZSJ1TLW8f8GP+B5 |
michael@428 | 807 | =AVpf |
michael@428 | 808 | -----END PGP SIGNATURE----- |