|
| 1 | +// SPDX-FileCopyrightText: 2026 Greenbone AG |
| 2 | +// |
| 3 | +// SPDX-License-Identifier: GPL-2.0-or-later WITH x11vnc-openssl-exception |
| 4 | + |
| 5 | +use std::env; |
| 6 | +use std::path::{Path, PathBuf}; |
| 7 | +use std::process::Command; |
| 8 | + |
| 9 | +const KRB5_VERSION: &str = "1.20"; |
| 10 | +const KRB5_PATCH: &str = "1"; |
| 11 | + |
| 12 | +fn main() { |
| 13 | + println!("cargo:rerun-if-changed=build.rs"); |
| 14 | + println!("cargo:rerun-if-changed=../../../../misc/openvas-krb5.c"); |
| 15 | + println!("cargo:rerun-if-changed=../../../../misc/openvas-krb5.h"); |
| 16 | + println!("cargo::rerun-if-env-changed=TARGET"); |
| 17 | + |
| 18 | + let target = env::var("TARGET").unwrap(); |
| 19 | + |
| 20 | + // Try to find static Kerberos libraries via pkg-config |
| 21 | + let build_path = build_krb5_from_source(&target); |
| 22 | + |
| 23 | + // Link against the built static libraries |
| 24 | + println!( |
| 25 | + "cargo:rustc-link-search=native={}", |
| 26 | + build_path.join("lib").display() |
| 27 | + ); |
| 28 | + println!("cargo:rustc-link-lib=static=krb5"); |
| 29 | + println!("cargo:rustc-link-lib=static=k5crypto"); |
| 30 | + println!("cargo:rustc-link-lib=static=com_err"); |
| 31 | + println!("cargo:rustc-link-lib=static=gssapi_krb5"); |
| 32 | + println!("cargo:rustc-link-lib=static=krb5support"); |
| 33 | + |
| 34 | + // Link system dependencies |
| 35 | + println!("cargo:rustc-link-lib=keyutils"); |
| 36 | + println!("cargo:rustc-link-lib=resolv"); |
| 37 | + |
| 38 | + let mut build = cc::Build::new(); |
| 39 | + build |
| 40 | + .file("../../../../misc/openvas-krb5.c") |
| 41 | + .include("../../../../misc") |
| 42 | + .include(build_path.join("include")) |
| 43 | + .opt_level(2); |
| 44 | + |
| 45 | + build.compile("openvas-krb5"); |
| 46 | + |
| 47 | + let bindings = bindgen::Builder::default() |
| 48 | + .header("../../../../misc/openvas-krb5.h") |
| 49 | + .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) |
| 50 | + .generate() |
| 51 | + .expect("Unable to generate bindings"); |
| 52 | + |
| 53 | + let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); |
| 54 | + bindings |
| 55 | + .write_to_file(out_path.join("bindings.rs")) |
| 56 | + .expect("Unable to write bindings") |
| 57 | +} |
| 58 | + |
| 59 | +fn build_krb5_from_source(target: &str) -> PathBuf { |
| 60 | + let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); |
| 61 | + let install_dir = out_dir.join("krb5-build"); |
| 62 | + |
| 63 | + let extract_dir = fetch_krb5(&out_dir); |
| 64 | + |
| 65 | + build_krb5(&extract_dir.join("src"), &install_dir, target); |
| 66 | + |
| 67 | + install_dir |
| 68 | +} |
| 69 | + |
| 70 | +fn fetch_krb5(destination: &Path) -> PathBuf { |
| 71 | + let folder_name = format!("krb5-{}.{}", KRB5_VERSION, KRB5_PATCH); |
| 72 | + let extract_path = destination.join(&folder_name); |
| 73 | + |
| 74 | + // Check if already downloaded and extracted |
| 75 | + if extract_path.join("src/configure").exists() { |
| 76 | + println!("cargo:warning=Kerberos source already downloaded, skipping"); |
| 77 | + return extract_path; |
| 78 | + } |
| 79 | + |
| 80 | + let tar_path = extract_path.with_added_extension("tar.gz"); |
| 81 | + |
| 82 | + let url = format!( |
| 83 | + "https://kerberos.org/dist/krb5/{}/{}.tar.gz", |
| 84 | + KRB5_VERSION, folder_name |
| 85 | + ); |
| 86 | + |
| 87 | + Command::new("curl") |
| 88 | + .args(["--fail", "-L", "-O", &url]) |
| 89 | + .current_dir(destination) |
| 90 | + .status() |
| 91 | + .unwrap(); |
| 92 | + |
| 93 | + Command::new("tar") |
| 94 | + .args(["-xzf", &tar_path.to_string_lossy()]) |
| 95 | + .current_dir(destination) |
| 96 | + .status() |
| 97 | + .unwrap(); |
| 98 | + |
| 99 | + extract_path |
| 100 | +} |
| 101 | + |
| 102 | +fn build_krb5(src: &Path, install_prefix: &Path, target: &str) { |
| 103 | + // Configure with prefix pointing to install location |
| 104 | + let status = Command::new("sh") |
| 105 | + .arg("-c") |
| 106 | + .arg(format!( |
| 107 | + "./configure --prefix={} --enable-static --disable-shared --without-system-verto --without-libedit --disable-rpath --host={}", |
| 108 | + install_prefix.display(), |
| 109 | + target |
| 110 | + )) |
| 111 | + .current_dir(src) |
| 112 | + .status() |
| 113 | + .expect("Failed to run configure"); |
| 114 | + |
| 115 | + if !status.success() { |
| 116 | + panic!("Configure failed"); |
| 117 | + } |
| 118 | + |
| 119 | + // Build everything (this may fail on utilities but libraries will build) |
| 120 | + let _ = Command::new("make").arg("-j").current_dir(src).status(); |
| 121 | + |
| 122 | + // Install what was built successfully |
| 123 | + let _ = Command::new("make") |
| 124 | + .arg("install") |
| 125 | + .current_dir(src) |
| 126 | + .status(); |
| 127 | +} |
0 commit comments