| #!/usr/bin/env python3 |
| # Copyright 2019 The ChromiumOS Authors |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| """Build openssh package.""" |
| |
| import glob |
| import logging |
| import os |
| from pathlib import Path |
| import sys |
| |
| FILESDIR = Path(__file__).resolve().parent |
| sys.path.insert(0, str(FILESDIR.parent.parent / "bin")) |
| |
| import ssh_client # pylint: disable=wrong-import-position |
| |
| |
| ARCHIVES = ("%(p)s.tar.gz",) |
| PATCHES = ( |
| "%(p)s.patch", |
| "%(p)s-write-disconnect.patch", |
| ) |
| |
| |
| def src_configure(metadata): |
| """Configure the source.""" |
| if os.path.exists("Makefile"): |
| logging.info("Makefile exists; skipping ./configure step") |
| return |
| |
| tc = metadata["toolchain"] |
| |
| EXTRA_LIBS = ["-lcrypto"] |
| EXTRA_CFLAGS = [ |
| "-DHAVE_SIGACTION", |
| "-DHAVE_TRUNCATE", |
| "-DHAVE_SETSID", |
| "-DHAVE_GETNAMEINFO", |
| "-DHAVE_GETADDRINFO", |
| "-DHAVE_GETCWD", |
| "-DHAVE_STATVFS", |
| "-DHAVE_FSTATVFS", |
| "-DHAVE_ENDGRENT", |
| "-DHAVE_FD_MASK", |
| "-include", |
| "sys/cdefs.h", |
| ] |
| |
| EXTRA_CONFIGURE_FLAGS = [ |
| # Log related settings. |
| "--disable-lastlog", |
| "--disable-utmp", |
| "--disable-utmpx", |
| "--disable-wtmp", |
| "--disable-wtmpx", |
| "--disable-pututline", |
| "--disable-pututxline", |
| # Various toolchain settings. |
| "--without-rpath", |
| "--without-Werror", |
| # Features we don't use. |
| "--without-audit", |
| "--without-libedit", |
| "--without-pam", |
| "--without-sandbox", |
| "--without-selinux", |
| "--without-shadow", |
| "--without-ssl-engine", |
| # Features we want. |
| # OpenSSL is needed for DSA/RSA key support. |
| "--with-openssl", |
| "--with-ldns", |
| "--with-zlib", |
| "--without-zlib-version-check", |
| # These don't work with newlib (used in PNaCl). |
| "--without-stackprotect", |
| "--without-hardening", |
| # Disable inet funcs we don't rely upon. |
| "ac_cv_func_inet_aton=no", |
| "ac_cv_func_inet_ntoa=no", |
| "ac_cv_func_inet_ntop=no", |
| # We set these to yes because openssh doesn't use them, so we want to |
| # disable the fallback implementations. If it starts needing them, we |
| # will notice with link errors. |
| "ac_cv_func_bindresvport_sa=yes", |
| "ac_cv_func_getgrouplist=yes", |
| "ac_cv_func_rresvport_af=yes", |
| ] |
| |
| cmd = [ |
| "./configure", |
| f"--build={tc.cbuild}", |
| f"--host={tc.chost}", |
| # The prefix path matches what is used at runtime. |
| "--prefix=/", |
| "--cache-file=../config.cache", |
| f"CFLAGS={' '.join(EXTRA_CFLAGS)}", |
| f"LIBS={' '.join(EXTRA_LIBS)}", |
| ] |
| ssh_client.run(cmd + EXTRA_CONFIGURE_FLAGS) |
| |
| # Build the html man pages. Since we're hooking the Makefile, we need can |
| # do this only after we've run configure. |
| with open("Makefile", "ab") as f: |
| f.writelines( |
| [ |
| b"html: $(MANPAGES_IN:%=%.html)\n", |
| b"%.html: %\n", |
| ( |
| b"\tmandoc -Thtml -I os=" |
| + metadata["p"].encode("utf-8") |
| + b" -O man=%N.%S.html $< >$@.tmp\n" |
| ), |
| b"\tmv $@.tmp $@\n", |
| ] |
| ) |
| |
| |
| def src_compile(metadata): |
| """Compile the source.""" |
| # These are the few objects we care about for our tools. |
| objects = [ |
| "ssh.o", |
| "readconf.o", |
| "clientloop.o", |
| "sshtty.o", |
| "sshconnect.o", |
| "sshconnect2.o", |
| "mux.o", |
| ] |
| |
| targets = objects + [ |
| # These are internal ssh libs that the objects above might use. |
| "libssh.a", |
| "openbsd-compat/libopenbsd-compat.a", |
| # The documentation we'll ship later on. |
| "html", |
| ] |
| |
| tc = metadata["toolchain"] |
| if tc.chost.startswith("wasm"): |
| targets += ["scp", "sftp", "ssh", "ssh-keygen"] |
| |
| ssh_client.emake(*targets) |
| ssh_client.run([tc.ar, "rcs", "libopenssh.a"] + objects) |
| |
| |
| def src_install(metadata): |
| """Install the package.""" |
| tc = metadata["toolchain"] |
| # Turn "8.0p1" into just "8.0". |
| major_minor_version = metadata["PV"][:3] |
| for lib in ( |
| "libopenssh.a", |
| "libssh.a", |
| "openbsd-compat/libopenbsd-compat.a", |
| ): |
| # Transform libssh.a to libssh-8.0.a. |
| base, ext = os.path.splitext(os.path.basename(lib)) |
| target = f"{base}-{major_minor_version}{ext}" |
| ssh_client.copy(lib, os.path.join(tc.libdir, target)) |
| |
| plugin_docs = ssh_client.OUTPUT / "plugin" / "docs" |
| plugin_docs.mkdir(parents=True, exist_ok=True) |
| for path in glob.glob("*.[0-9].html"): |
| ssh_client.copy(path, plugin_docs / path) |
| |
| |
| ssh_client.build_package(sys.modules[__name__], "pnacl") |