Skip to main content

security_framework_sys/
keychain.rs

1#[cfg(target_os = "macos")]
2use core_foundation_sys::base::CFTypeRef;
3#[cfg(target_os = "macos")]
4use core_foundation_sys::base::{Boolean, CFTypeID, OSStatus};
5#[cfg(target_os = "macos")]
6use std::os::raw::{c_char, c_uint, c_void};
7
8#[cfg(target_os = "macos")]
9use crate::base::SecKeychainItemRef;
10#[cfg(target_os = "macos")]
11use crate::base::{SecAccessRef, SecKeychainRef};
12
13#[cfg(target_os = "macos")]
14pub const SEC_KEYCHAIN_SETTINGS_VERS1: c_uint = 1;
15
16#[repr(C)]
17#[cfg(target_os = "macos")]
18pub struct SecKeychainSettings {
19    pub version: c_uint,
20    pub lockOnSleep: Boolean,
21    pub useLockInterval: Boolean,
22    pub lockInterval: c_uint,
23}
24
25/// Like Apple's headers, it assumes Little Endian,
26/// as there are no supported Big Endian machines any more :(
27macro_rules! char_lit {
28    ($e:expr) => {
29        ($e[3] as u32) + (($e[2] as u32) << 8) + (($e[1] as u32) << 16) + (($e[0] as u32) << 24)
30    };
31}
32
33macro_rules! char_lit_swapped {
34    ($e:expr) => {
35        ($e[0] as u32) + (($e[1] as u32) << 8) + (($e[2] as u32) << 16) + (($e[3] as u32) << 24)
36    };
37}
38
39#[repr(u32)]
40#[derive(Copy, Clone, Eq, PartialEq, Debug)]
41#[allow(clippy::upper_case_acronyms)]
42pub enum SecProtocolType {
43    #[cfg_attr(not(target_os = "macos"), deprecated(note = "macOS only"))]
44    FTP = char_lit!(b"ftp "),
45    #[cfg_attr(not(target_os = "macos"), deprecated(note = "macOS only"))]
46    FTPAccount = char_lit!(b"ftpa"),
47    #[cfg_attr(not(target_os = "macos"), deprecated(note = "macOS only"))]
48    HTTP = char_lit!(b"http"),
49    #[cfg_attr(not(target_os = "macos"), deprecated(note = "macOS only"))]
50    IRC = char_lit!(b"irc "),
51    #[cfg_attr(not(target_os = "macos"), deprecated(note = "macOS only"))]
52    NNTP = char_lit!(b"nntp"),
53    #[cfg_attr(not(target_os = "macos"), deprecated(note = "macOS only"))]
54    POP3 = char_lit!(b"pop3"),
55    #[cfg_attr(not(target_os = "macos"), deprecated(note = "macOS only"))]
56    SMTP = char_lit!(b"smtp"),
57    #[cfg_attr(not(target_os = "macos"), deprecated(note = "macOS only"))]
58    SOCKS = char_lit!(b"sox "),
59    #[cfg_attr(not(target_os = "macos"), deprecated(note = "macOS only"))]
60    IMAP = char_lit!(b"imap"),
61    #[cfg_attr(not(target_os = "macos"), deprecated(note = "macOS only"))]
62    LDAP = char_lit!(b"ldap"),
63    #[cfg_attr(not(target_os = "macos"), deprecated(note = "macOS only"))]
64    AppleTalk = char_lit!(b"atlk"),
65    #[cfg_attr(not(target_os = "macos"), deprecated(note = "macOS only"))]
66    AFP = char_lit!(b"afp "),
67    #[cfg_attr(not(target_os = "macos"), deprecated(note = "macOS only"))]
68    Telnet = char_lit!(b"teln"),
69    #[cfg_attr(not(target_os = "macos"), deprecated(note = "macOS only"))]
70    SSH = char_lit!(b"ssh "),
71    #[cfg_attr(not(target_os = "macos"), deprecated(note = "macOS only"))]
72    FTPS = char_lit!(b"ftps"),
73    #[cfg_attr(not(target_os = "macos"), deprecated(note = "macOS only"))]
74    HTTPS = char_lit!(b"htps"),
75    #[cfg_attr(not(target_os = "macos"), deprecated(note = "macOS only"))]
76    HTTPProxy = char_lit!(b"htpx"),
77    #[cfg_attr(not(target_os = "macos"), deprecated(note = "macOS only"))]
78    HTTPSProxy = char_lit!(b"htsx"),
79    #[cfg_attr(not(target_os = "macos"), deprecated(note = "macOS only"))]
80    FTPProxy = char_lit!(b"ftpx"),
81    #[cfg_attr(not(target_os = "macos"), deprecated(note = "macOS only"))]
82    CIFS = char_lit!(b"cifs"),
83    #[cfg_attr(not(target_os = "macos"), deprecated(note = "macOS only"))]
84    SMB = char_lit!(b"smb "),
85    #[cfg_attr(not(target_os = "macos"), deprecated(note = "macOS only"))]
86    RTSP = char_lit!(b"rtsp"),
87    #[cfg_attr(not(target_os = "macos"), deprecated(note = "macOS only"))]
88    RTSPProxy = char_lit!(b"rtsx"),
89    #[cfg_attr(not(target_os = "macos"), deprecated(note = "macOS only"))]
90    DAAP = char_lit!(b"daap"),
91    #[cfg_attr(not(target_os = "macos"), deprecated(note = "macOS only"))]
92    EPPC = char_lit!(b"eppc"),
93    #[cfg_attr(not(target_os = "macos"), deprecated(note = "macOS only"))]
94    IPP = char_lit!(b"ipp "),
95    #[cfg_attr(not(target_os = "macos"), deprecated(note = "macOS only"))]
96    NNTPS = char_lit!(b"ntps"),
97    #[cfg_attr(not(target_os = "macos"), deprecated(note = "macOS only"))]
98    LDAPS = char_lit!(b"ldps"),
99    #[cfg_attr(not(target_os = "macos"), deprecated(note = "macOS only"))]
100    TelnetS = char_lit!(b"tels"),
101    #[cfg_attr(not(target_os = "macos"), deprecated(note = "macOS only"))]
102    IMAPS = char_lit!(b"imps"),
103    #[cfg_attr(not(target_os = "macos"), deprecated(note = "macOS only"))]
104    IRCS = char_lit!(b"ircs"),
105    #[cfg_attr(not(target_os = "macos"), deprecated(note = "macOS only"))]
106    POP3S = char_lit!(b"pops"),
107    #[cfg_attr(not(target_os = "macos"), deprecated(note = "macOS only"))]
108    CVSpserver = char_lit!(b"cvsp"),
109    #[cfg_attr(not(target_os = "macos"), deprecated(note = "macOS only"))]
110    SVN = char_lit!(b"svn "),
111    Any = 0,
112}
113
114#[repr(u32)]
115#[derive(Copy, Clone, Eq, PartialEq, Debug)]
116#[allow(clippy::upper_case_acronyms)]
117pub enum SecAuthenticationType {
118    // [sic] Apple has got two related enums each with a different endianness!
119    NTLM = char_lit_swapped!(b"ntlm"),
120    #[cfg_attr(not(target_os = "macos"), deprecated(note = "macOS only"))]
121    MSN = char_lit_swapped!(b"msna"),
122    #[cfg_attr(not(target_os = "macos"), deprecated(note = "macOS only"))]
123    DPA = char_lit_swapped!(b"dpaa"),
124    #[cfg_attr(not(target_os = "macos"), deprecated(note = "macOS only"))]
125    RPA = char_lit_swapped!(b"rpaa"),
126    #[cfg_attr(not(target_os = "macos"), deprecated(note = "macOS only"))]
127    HTTPBasic = char_lit_swapped!(b"http"),
128    #[cfg_attr(not(target_os = "macos"), deprecated(note = "macOS only"))]
129    HTTPDigest = char_lit_swapped!(b"httd"),
130    #[cfg_attr(not(target_os = "macos"), deprecated(note = "macOS only"))]
131    HTMLForm = char_lit_swapped!(b"form"),
132    #[cfg_attr(not(target_os = "macos"), deprecated(note = "macOS only"))]
133    Default = char_lit_swapped!(b"dflt"),
134    Any = 0,
135}
136
137#[repr(i32)]
138#[derive(Copy, Clone, Eq, PartialEq, Debug)]
139pub enum SecPreferencesDomain {
140    User = 0,
141    System = 1,
142    Common = 2,
143    Dynamic = 3,
144}
145
146extern "C" {
147    #[cfg(target_os = "macos")]
148    pub fn SecKeychainGetTypeID() -> CFTypeID;
149    #[cfg(target_os = "macos")]
150    pub fn SecKeychainCopyDefault(keychain: *mut SecKeychainRef) -> OSStatus;
151    #[cfg(target_os = "macos")]
152    pub fn SecKeychainCopyDomainDefault(
153        domain: SecPreferencesDomain,
154        keychain: *mut SecKeychainRef,
155    ) -> OSStatus;
156    #[cfg(target_os = "macos")]
157    pub fn SecKeychainCreate(
158        pathName: *const c_char,
159        passwordLength: c_uint,
160        password: *const c_void,
161        promptUser: Boolean,
162        initialAccess: SecAccessRef,
163        keychain: *mut SecKeychainRef,
164    ) -> OSStatus;
165    #[cfg(target_os = "macos")]
166    pub fn SecKeychainOpen(pathName: *const c_char, keychain: *mut SecKeychainRef) -> OSStatus;
167    #[cfg(target_os = "macos")]
168    pub fn SecKeychainUnlock(
169        keychain: SecKeychainRef,
170        passwordLength: c_uint,
171        password: *const c_void,
172        usePassword: Boolean,
173    ) -> OSStatus;
174    #[cfg(target_os = "macos")]
175    pub fn SecKeychainFindGenericPassword(
176        keychainOrArray: CFTypeRef,
177        serviceNameLength: u32,
178        serviceName: *const c_char,
179        accountNameLength: u32,
180        accountName: *const c_char,
181        passwordLength: *mut u32,
182        passwordData: *mut *mut c_void,
183        itemRef: *mut SecKeychainItemRef,
184    ) -> OSStatus;
185
186    #[cfg(target_os = "macos")]
187    pub fn SecKeychainFindInternetPassword(
188        keychainOrArray: CFTypeRef,
189        serverNameLength: u32,
190        serverName: *const c_char,
191        securityDomainLength: u32,
192        securityDomain: *const c_char,
193        accountNameLength: u32,
194        accountName: *const c_char,
195        pathLength: u32,
196        path: *const c_char,
197        port: u16,
198        protocol: SecProtocolType,
199        authenticationType: SecAuthenticationType,
200        passwordLength: *mut u32,
201        passwordData: *mut *mut c_void,
202        itemRef: *mut SecKeychainItemRef,
203    ) -> OSStatus;
204
205    #[cfg(target_os = "macos")]
206    pub fn SecKeychainAddGenericPassword(
207        keychain: SecKeychainRef,
208        serviceNameLength: u32,
209        serviceName: *const c_char,
210        accountNameLength: u32,
211        accountName: *const c_char,
212        passwordLength: u32,
213        passwordData: *const c_void,
214        itemRef: *mut SecKeychainItemRef,
215    ) -> OSStatus;
216
217    #[cfg(target_os = "macos")]
218    pub fn SecKeychainAddInternetPassword(
219        keychain: SecKeychainRef,
220        serverNameLength: u32,
221        serverName: *const c_char,
222        securityDomainLength: u32,
223        securityDomain: *const c_char,
224        accountNameLength: u32,
225        accountName: *const c_char,
226        pathLength: u32,
227        path: *const c_char,
228        port: u16,
229        protocol: SecProtocolType,
230        authenticationType: SecAuthenticationType,
231        passwordLength: u32,
232        passwordData: *const c_void,
233        itemRef: *mut SecKeychainItemRef,
234    ) -> OSStatus;
235
236    #[cfg(target_os = "macos")]
237    pub fn SecKeychainSetSettings(
238        keychain: SecKeychainRef,
239        newSettings: *const SecKeychainSettings,
240    ) -> OSStatus;
241
242    #[cfg(target_os = "macos")]
243    pub fn SecKeychainGetUserInteractionAllowed(state: *mut Boolean) -> OSStatus;
244
245    #[cfg(target_os = "macos")]
246    pub fn SecKeychainSetUserInteractionAllowed(state: Boolean) -> OSStatus;
247}