apple_security_framework_sys/
keychain.rs

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