summarylogtreecommitdiffstats
diff options
context:
space:
mode:
authorMantas Mikulėnas2019-10-19 16:48:21 +0300
committerMantas Mikulėnas2019-10-19 16:52:39 +0300
commitf0ff00ab66f52aff0caec6f7ddded9f721acb981 (patch)
tree6d69594b353e61036b9c85fd2db81cef50e32a3e
parent0512b6bd4b941c55f71a76523e8e0d67d3bfb20d (diff)
downloadaur-f0ff00ab66f52aff0caec6f7ddded9f721acb981.tar.gz
release 2019-10-15
-rw-r--r--.SRCINFO12
-rw-r--r--LocalSign.service2
-rw-r--r--PKGBUILD29
-rwxr-xr-xissunpack.py154
4 files changed, 183 insertions, 14 deletions
diff --git a/.SRCINFO b/.SRCINFO
index 670eea408b3b..8f85c033ac91 100644
--- a/.SRCINFO
+++ b/.SRCINFO
@@ -1,15 +1,19 @@
pkgbase = rcsc-localsign
pkgdesc = RCSC LocalSign smartcard signing server (for GoSign and Elektroninis.lt)
- pkgver = 20180518.jar1.7.1
+ pkgver = 20191015
pkgrel = 1
arch = x86_64
+ makedepends = p7zip
+ makedepends = python
depends = java-runtime
- source = rc-localserver-20180518.jar1.7.1.zip::http://downloads.registrucentras.lt/bylos/dokumentai/rcsc/localsign/rc-localserver-install.zip
+ source = rc-localsign-20191015.exe::http://www.elektroninis.lt/bylos/dokumentai/rcsc/localsign/localsign-install.exe
+ source = issunpack.py
source = LocalSign.service
source = RCSC_RootCA_4f001ba124bdcb8848bebd3f2b62c7c5.pem
source = VI_Registru_Centras_RCSC_RootCA_03a3a457b5f0f3864a1163e898ff169c.pem
- sha256sums = 52832e14e510f511558bfce97735ffd48796f863596edd8644796328667453f3
- sha256sums = 6c45b7017f3c46fe9551b7ed4c69339fa1a15df3eb02d2dd71558f49866fdd4b
+ sha256sums = 17915f63108bc3f5279581589ae2616d908c9a28a71125df4ccf3a5884ceddeb
+ sha256sums = bc7ecb4696dfaf3ffb3322f36cf04fd1413012dc7da6089448ee66feb6982cc0
+ sha256sums = 35540b47c9687397eb5da6a344970693975ec3479f86e79955b4642a33a23a8d
sha256sums = c1bd62c20a74c779e4b2d645736663f8d7451dccce9c886f6e7c1bedfeb43128
sha256sums = 92f7673db77de2b46b1bf91870dbe9a28defb3f9b939e819af97cb6d30763945
diff --git a/LocalSign.service b/LocalSign.service
index 6bf84ba46df5..8d3cf2e72f76 100644
--- a/LocalSign.service
+++ b/LocalSign.service
@@ -4,7 +4,7 @@ Description=RCSC LocalSign token server
[Service]
Type=simple
User=daemon
-ExecStart=/usr/bin/java -jar /opt/RCSC/LocalSign/local-webserver-1.7.1.jar
+ExecStart=/usr/bin/java -jar /opt/RCSC/LocalSign/local_webserver.jar
KillSignal=SIGKILL
[Install]
diff --git a/PKGBUILD b/PKGBUILD
index deff910dfdcc..fe9749d581a1 100644
--- a/PKGBUILD
+++ b/PKGBUILD
@@ -1,24 +1,35 @@
pkgname=rcsc-localsign
-pkgver=20180518.jar1.7.1
-#pkgver=20191015
+pkgver=20191015
pkgrel=1
pkgdesc="RCSC LocalSign smartcard signing server (for GoSign and Elektroninis.lt)"
arch=(x86_64)
depends=(java-runtime)
-source=("rc-localserver-$pkgver.zip::http://downloads.registrucentras.lt/bylos/dokumentai/rcsc/localsign/rc-localserver-install.zip"
+makedepends=(p7zip python)
+source=("rc-localsign-$pkgver.exe::http://www.elektroninis.lt/bylos/dokumentai/rcsc/localsign/localsign-install.exe"
+ issunpack.py
LocalSign.service
RCSC_RootCA_4f001ba124bdcb8848bebd3f2b62c7c5.pem
VI_Registru_Centras_RCSC_RootCA_03a3a457b5f0f3864a1163e898ff169c.pem)
-sha256sums=('52832e14e510f511558bfce97735ffd48796f863596edd8644796328667453f3'
- '6c45b7017f3c46fe9551b7ed4c69339fa1a15df3eb02d2dd71558f49866fdd4b'
+sha256sums=('17915f63108bc3f5279581589ae2616d908c9a28a71125df4ccf3a5884ceddeb'
+ 'bc7ecb4696dfaf3ffb3322f36cf04fd1413012dc7da6089448ee66feb6982cc0'
+ '35540b47c9687397eb5da6a344970693975ec3479f86e79955b4642a33a23a8d'
'c1bd62c20a74c779e4b2d645736663f8d7451dccce9c886f6e7c1bedfeb43128'
'92f7673db77de2b46b1bf91870dbe9a28defb3f9b939e819af97cb6d30763945')
-# TODO: Figure out how to unpack ISSetupStream for the latest version
-#source=("http://www.elektroninis.lt/bylos/dokumentai/rcsc/localsign/localsign-install.exe")
-#sha256sums=('17915f63108bc3f5279581589ae2616d908c9a28a71125df4ccf3a5884ceddeb')
+
+prepare() {
+ msg2 "Extracting InstallShield self-executable..."
+ 7z -so x "rc-localsign-$pkgver.exe" "[0]" > isstream.bin
+ msg2 "Extracting InstallShield data stream..."
+ mkdir -p setup_files
+ python issunpack.py isstream.bin setup_files
+ msg2 "Extracting Windows Installer package..."
+ 7z -y -omsi_files x "setup_files/RC LocalSign.msi" Data1.cab
+ msg2 "Extracting Windows Installer cabinet..."
+ 7z -y -ocab_files x "msi_files/Data1.cab"
+}
package() {
- install -Dm644 -t "$pkgdir"/opt/RCSC/LocalSign local-webserver-1.7.1.jar
+ install -Dm644 -t "$pkgdir"/opt/RCSC/LocalSign cab_files/local_webserver.jar
install -Dm644 -t "$pkgdir"/usr/lib/systemd/system LocalSign.service
install -Dm644 -t "$pkgdir"/usr/share/ca-certificates/trust-source/anchors *.pem
}
diff --git a/issunpack.py b/issunpack.py
new file mode 100755
index 000000000000..5a7ce6c9e01e
--- /dev/null
+++ b/issunpack.py
@@ -0,0 +1,154 @@
+#!/usr/bin/env python3
+# InstallShield ISSetupStream extractor
+# (c) 2019 Mantas Mikulėnas <grawity@gmail.com>
+#
+# Based on code from <https://github.com/lifenjoiner/ISx>
+# (c) 2017 lifenjoiner
+#
+# Released under the MIT License
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+import os
+import struct
+import sys
+import zlib
+
+class BinaryReader():
+ def __init__(self, fh):
+ self.fh = fh
+
+ def _debug(self, typ, data):
+ if os.environ.get("DEBUG"):
+ c_on = "\033[33m" if sys.stderr.isatty() else ""
+ c_off = "\033[m" if sys.stderr.isatty() else ""
+ print(c_on, "#", typ, repr(data)[:1024], c_off, file=sys.stderr)
+ return data
+
+ def read(self, length):
+ buf = self.fh.read(length)
+ if len(buf) < length:
+ if len(buf) == 0:
+ raise EOFError("Hit EOF after 0/%d bytes" % length)
+ else:
+ raise IOError("Hit EOF after %d/%d bytes" % (len(buf), length))
+ return self._debug("raw[%d]" % length, buf)
+
+ def _read_fmt(self, length, fmt, typ):
+ buf = self.fh.read(length)
+ if len(buf) < length:
+ if len(buf) == 0:
+ raise EOFError("Hit EOF after 0/%d bytes" % length)
+ else:
+ raise IOError("Hit EOF after %d/%d bytes" % (len(buf), length))
+ data, = struct.unpack(fmt, buf)
+ return self._debug(typ, data)
+
+ def read_u8(self):
+ return self._read_fmt(1, "B", "byte")
+
+ def read_u16_le(self):
+ return self._read_fmt(2, "<H", "short")
+
+ def read_u16_be(self):
+ return self._read_fmt(2, ">H", "short")
+
+ def read_u32_le(self):
+ return self._read_fmt(4, "<L", "long")
+
+ def read_u32_be(self):
+ return self._read_fmt(4, ">L", "long")
+
+ def read_u64_le(self):
+ return self._read_fmt(8, "<Q", "quad")
+
+ def read_u64_be(self):
+ return self._read_fmt(8, ">Q", "quad")
+
+class ISSetupStreamReader(BinaryReader):
+ def read_iss_header(self):
+ magic = self.read(14)
+ assert(magic == b'ISSetupStream\x00')
+ num_files = self.read_u16_le()
+ _ = self.read_u32_le()
+ _ = self.read(8)
+ _ = self.read_u16_le()
+ _ = self.read(16)
+ return (num_files,)
+
+ def read_file_header(self):
+ name_len = self.read_u32_le()
+ enc_flags = self.read_u32_le()
+ _ = self.read(2)
+ file_len = self.read_u32_le()
+ _ = self.read(8)
+ is_unicode = self.read_u16_le()
+ time1 = self.read_u64_le()
+ time2 = self.read_u64_le()
+ time3 = self.read_u64_le()
+ file_name = self.read(name_len).decode("utf-16le")
+ return (file_name, file_len, enc_flags, is_unicode, time1, time2, time3)
+
+ def read_file(self):
+ (file_name, file_len, enc_flags, is_unicode, time1, time2, time3) = self.read_file_header()
+ print("file %r" % file_name)
+ file_data = self.read(file_len)
+
+ def gen_key(seed):
+ magic = [0x13, 0x35, 0x86, 0x07]
+ return bytes([seed[i] ^ magic[i % len(magic)] for i in range(len(seed))])
+
+ def decode_byte(b, k):
+ return (~(k ^ (b << 4 | b >> 4))) & 0xFF
+
+ def decode_chunk(buf, key):
+ return bytes([decode_byte(buf[i], key[i % len(key)]) for i in range(len(buf))])
+
+ seed = file_name.encode("utf-8")
+ key = gen_key(seed)
+
+ is_type_4 = bool(enc_flags & 4)
+ if is_type_4:
+ # Decode in chunks of 1024, i.e. restarting at key[0] every time
+ # Just round the key to exactly 1024 bytes and it'll work automatically
+ key += key * (1024 // len(key))
+ key = key[:1024]
+ data = decode_chunk(file_data, key)
+ else:
+ data = decode_chunk(file_data, key)
+
+ if is_unicode:
+ assert(data[0:2] == b'\x78\x9c')
+ data = zlib.decompress(data)
+
+ return (file_name, data)
+
+ def extract_all(self, dir="."):
+ (num_files,) = self.read_iss_header()
+ for i in range(num_files):
+ (file_name, file_data) = self.read_file()
+ file_name = file_name.replace("/", "\x01")
+ with open(os.path.join(dir, file_name), "wb") as fh:
+ fh.write(file_data)
+
+in_file = sys.argv[1]
+out_dir = sys.argv[2]
+
+with open(in_file, "rb") as fh:
+ ISSetupStreamReader(fh).extract_all(out_dir)