Skip to content

Commit

Permalink
Merge pull request #1811 from zowe/feat/secrets/core-foundation
Browse files Browse the repository at this point in the history
feat(secrets): Use `core-foundation-rs` instead of `security-framework` for macOS logic
  • Loading branch information
traeok authored Sep 28, 2023
2 parents 96febb0 + 7a3b964 commit d637e90
Show file tree
Hide file tree
Showing 17 changed files with 783 additions and 163 deletions.
6 changes: 3 additions & 3 deletions npm-shrinkwrap.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions packages/cli/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

All notable changes to the Zowe CLI package will be documented in this file.

## Recent Changes

- BugFix: Bump Secrets SDK to `7.18.6` to use `core-foundation-rs` instead of the now-archived `security-framework` crate, and to include the edge-case bug fix for Linux.

## `7.18.5`

- BugFix: Bump Secrets SDK to `7.18.5` to resolve build failures for FreeBSD users.
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@
"which": "^2.0.2"
},
"optionalDependencies": {
"@zowe/secrets-for-zowe-sdk": "7.18.5"
"@zowe/secrets-for-zowe-sdk": "7.18.6"
},
"engines": {
"node": ">=14.0.0"
Expand Down
5 changes: 5 additions & 0 deletions packages/secrets/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

All notable changes to the Zowe Secrets SDK package will be documented in this file.

## `7.18.6`

- BugFix: Use `core-foundation-rs` instead of `security-framework` for macOS logic, as `security-framework` is now archived. [#1802](https://github.com/zowe/zowe-cli/issues/1802)
- BugFix: Resolve bug where `findCredentials` scenarios with one match causes a segmentation fault on Linux.

## `7.18.5`

- BugFix: Enable `KeyringError::Library` enum variant to fix building on FreeBSD targets.
Expand Down
2 changes: 1 addition & 1 deletion packages/secrets/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"description": "Credential management facilities for Imperative, Zowe CLI, and extenders.",
"repository": "https://github.com/zowe/zowe-cli.git",
"author": "Zowe",
"version": "7.18.5",
"version": "7.18.6",
"homepage": "https://github.com/zowe/zowe-cli/tree/master/packages/secrets#readme",
"bugs": {
"url": "https://github.com/zowe/zowe-cli/issues"
Expand Down
81 changes: 22 additions & 59 deletions packages/secrets/src/keyring/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 8 additions & 6 deletions packages/secrets/src/keyring/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,20 @@ features = [
version = "0.48.0"

[target.'cfg(target_os = "macos")'.dependencies]
security-framework = "2.9.1"
core-foundation = "0.9.3"
core-foundation-sys = "0.8.4"

[target.'cfg(any(target_os = "freebsd", target_os = "linux"))'.dependencies]
glib = "0.17.10"
gio = "0.17.10"
libsecret = "0.3.0"
libsecret-sys = "0.3.0"
glib = "0.18.2"
glib-sys = "0.18.1"
gio = "0.18.2"
libsecret = "0.4.0"
libsecret-sys = "0.4.0"

[build-dependencies]
napi-build = "2"

[profile.release]
lto = true
opt-level = "z" # Optimize for size.
strip = "symbols"
strip = "symbols"
11 changes: 11 additions & 0 deletions packages/secrets/src/keyring/__test__/index.spec.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,17 @@ test.serial(
}
);

test.serial("findCredentials works when only one credential is found", async (t) => {
await setPassword("TestKeyring2", "TestOneCred", "pass");

const creds = await findCredentials("TestKeyring2");
t.deepEqual(creds, [{
account: "TestOneCred",
password: "pass"
}]);
await deletePassword("TestKeyring2", "TestOneCred");
});

test.serial("findPassword for ASCII string", async (t) => {
const pw = await findPassword("TestKeyring/TestASCII");
t.is(pw, "ASCII string");
Expand Down
1 change: 1 addition & 0 deletions packages/secrets/src/keyring/src/os/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub enum KeyringError {
#[error("[keyring] {name:?} library returned an error:\n\n{details:?}")]
Library { name: String, details: String },

#[cfg(not(target_os = "macos"))]
#[error("[keyring] An OS error has occurred:\n\n{0}")]
Os(String),

Expand Down
66 changes: 66 additions & 0 deletions packages/secrets/src/keyring/src/os/mac/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
use crate::os::mac::ffi::SecCopyErrorMessageString;
use core_foundation::base::TCFType;
use core_foundation::string::CFString;
use core_foundation_sys::base::OSStatus;
use std::fmt::{Debug, Display, Formatter};
use std::num::NonZeroI32;

#[derive(Copy, Clone)]
pub struct Error(NonZeroI32);

/// errSecItemNotFound
pub const ERR_SEC_ITEM_NOT_FOUND: i32 = -25300;

impl Error {
#[inline]
#[must_use]
pub fn from_code(code: OSStatus) -> Self {
Self(NonZeroI32::new(code).unwrap_or_else(|| NonZeroI32::new(1).unwrap()))
}

pub fn code(self) -> i32 {
self.0.get() as _
}

/// Gets the message matching an OSStatus error code, if one exists.
pub fn message(&self) -> Option<String> {
unsafe {
let s = SecCopyErrorMessageString(self.code(), std::ptr::null_mut());
if s.is_null() {
None
} else {
Some(CFString::wrap_under_create_rule(s).to_string())
}
}
}
}

impl Debug for Error {
fn fmt(&self, fmt: &mut Formatter<'_>) -> std::fmt::Result {
let mut builder = fmt.debug_struct("Error");
builder.field("code", &self.0);
if let Some(message) = self.message() {
builder.field("message", &message);
}
builder.finish()
}
}

impl Display for Error {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self.message() {
Some(msg) => write!(f, "{}", msg),
None => write!(f, "code: {}", self.code()),
}
}
}

/// Handles the OSStatus code from macOS FFI calls (error handling helper fn)
#[inline(always)]
pub fn handle_os_status(err: OSStatus) -> Result<(), Error> {
match err {
// errSecSuccess
0 => Ok(()),
err => Err(Error::from_code(err)),
}
}
Loading

0 comments on commit d637e90

Please sign in to comment.