diff --git a/.gitignore b/.gitignore index 29f7c3a4..52d47ac9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ /doc/ -/target/ -/Cargo.lock +target/ +Cargo.lock diff --git a/Cargo.toml b/Cargo.toml index 22414a76..e278c264 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,28 +4,27 @@ name = "openssl" version = "0.0.1" authors = ["Steven Fackler "] +links = "openssl" +build = "src/build.rs" + +[features] +tlsv1_2 = [] +tlsv1_1 = [] +sslv2 = [] + +[build-dependencies.pkg-config] +git = "https://github.com/alexcrichton/pkg-config-rs" diff --git a/openssl-sys/LICENSE-MIT b/openssl-sys/LICENSE-MIT new file mode 100644 index 00000000..39e0ed66 --- /dev/null +++ b/openssl-sys/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2014 Alex Crichton + +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. diff --git a/openssl-sys/src/build.rs b/openssl-sys/src/build.rs new file mode 100644 index 00000000..f32ced0e --- /dev/null +++ b/openssl-sys/src/build.rs @@ -0,0 +1,22 @@ +extern crate "pkg-config" as pkg_config; + +use std::os; + +fn main() { + if pkg_config::find_library("openssl").is_err() { + let mut flags = " -l crypto -l ssl".to_string(); + + let target = os::getenv("TARGET").unwrap(); + + let win_pos = target.find_str("windows") + .or(target.find_str("win32")) + .or(target.find_str("win64")); + + // It's fun, but it looks like win32 and win64 both + // have all the libs with 32 sufix + if win_pos.is_some() { + flags.push_str(" -l gdi32 -l wsock32"); + } + println!("cargo:rustc-flags={}", flags); + } +} diff --git a/src/ffi.rs b/openssl-sys/src/lib.rs old mode 100644 new mode 100755 similarity index 97% rename from src/ffi.rs rename to openssl-sys/src/lib.rs index e67f444d..9eb3e930 --- a/src/ffi.rs +++ b/openssl-sys/src/lib.rs @@ -1,5 +1,9 @@ #![allow(non_camel_case_types, non_upper_case_globals, non_snake_case)] #![allow(dead_code)] + +extern crate libc; +extern crate sync; + use libc::{c_void, c_int, c_char, c_ulong, c_long, c_uint, c_uchar, size_t}; use std::mem; use std::ptr; @@ -176,27 +180,6 @@ pub const X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE: c_int = 45; pub const X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: c_int = 53; pub const X509_V_OK: c_int = 0; -#[cfg(not(target_os = "nacl"))] -mod link { - #[cfg( any( all(target_os = "macos", feature = "tlsv1_1"), - all(target_os = "macos", feature = "tlsv1_2")))] - #[link(name="ssl.1.0.0")] - #[link(name="crypto.1.0.0")] - extern {} - - #[cfg(any( not( target_os = "macos"), - all(target_os = "macos", not(feature = "tlsv1_1"), - not(feature = "tlsv1_2"))))] - #[link(name="ssl")] - #[link(name="crypto")] - extern {} - - #[cfg(target_os = "win32")] - #[link(name="gdi32")] - #[link(name="wsock32")] - extern { } -} - static mut MUTEXES: *mut Vec = 0 as *mut Vec; extern fn locking_function(mode: c_int, n: c_int, _file: *const c_char, @@ -479,3 +462,5 @@ extern "C" { pub fn i2d_RSAPrivateKey(k: *mut RSA, buf: *const *mut u8) -> c_int; pub fn d2i_RSAPrivateKey(k: *const *mut RSA, buf: *const *const u8, len: c_uint) -> *mut RSA; } + +pub mod probe; diff --git a/openssl-sys/src/probe.rs b/openssl-sys/src/probe.rs new file mode 100644 index 00000000..fc162028 --- /dev/null +++ b/openssl-sys/src/probe.rs @@ -0,0 +1,72 @@ +use std::os; +use std::io::fs::PathExtensions; + +pub struct ProbeResult { + pub cert_file: Option, + pub cert_dir: Option, +} + +/// Probe the system for the directory in which CA certificates should likely be +/// found. +/// +/// This will only search known system locations. +pub fn find_certs_dirs() -> Vec { + // see http://gagravarr.org/writing/openssl-certs/others.shtml + [ + "/var/ssl", + "/usr/share/ssl", + "/usr/local/ssl", + "/usr/local/openssl", + "/usr/local/share", + "/usr/lib/ssl", + "/usr/ssl", + "/etc/openssl", + "/etc/pki/tls", + "/etc/ssl", + ].iter().map(|s| Path::new(*s)).filter(|p| { + p.exists() + }).collect() +} + +pub fn init_ssl_cert_env_vars() { + let ProbeResult { cert_file, cert_dir } = probe(); + match cert_file { + Some(path) => put("SSL_CERT_FILE", path), + None => {} + } + match cert_dir { + Some(path) => put("SSL_CERT_DIR", path), + None => {} + } + + fn put(var: &str, path: Path) { + // Don't stomp over what anyone else has set + match os::getenv(var) { + Some(..) => {} + None => os::setenv(var, path), + } + } +} + +pub fn probe() -> ProbeResult { + let mut result = ProbeResult { + cert_file: os::getenv("SSL_CERT_FILE").map(Path::new), + cert_dir: os::getenv("SSL_CERT_DIR").map(Path::new), + }; + for certs_dir in find_certs_dirs().iter() { + // cert.pem looks to be an openssl 1.0.1 thing, while + // certs/ca-certificates.crt appears to be a 0.9.8 thing + try(&mut result.cert_file, certs_dir.join("cert.pem")); + try(&mut result.cert_file, certs_dir.join("certs/ca-certificates.crt")); + try(&mut result.cert_file, certs_dir.join("certs/ca-root-nss.crt")); + + try(&mut result.cert_dir, certs_dir.join("certs")); + } + result +} + +fn try(dst: &mut Option, val: Path) { + if dst.is_none() && val.exists() { + *dst = Some(val); + } +} diff --git a/src/lib.rs b/src/lib.rs index 456c8c7d..a974e399 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,8 +9,7 @@ extern crate libc; extern crate serialize; extern crate sync; -#[cfg(target_os = "nacl")] -extern crate "openssl-sys" as _unused; +extern crate "openssl-sys" as ffi; mod macros; @@ -18,6 +17,5 @@ pub mod asn1; pub mod bn; pub mod bio; pub mod crypto; -mod ffi; pub mod ssl; pub mod x509;