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