security_framework_sys/
keychain.rs

1#[cfg(target_os = "macos")]
2use core_foundation_sys::base::CFTypeRef;
3use core_foundation_sys::base::{Boolean, CFTypeID, OSStatus};
4use std::os::raw::{c_char, c_uint, c_void};
5
6#[cfg(target_os = "macos")]
7use crate::base::SecKeychainItemRef;
8use crate::base::{SecAccessRef, SecKeychainRef};
9
10pub const SEC_KEYCHAIN_SETTINGS_VERS1: c_uint = 1;
11
12#[repr(C)]
13pub 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 :(
22macro_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
28macro_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)]
37pub 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)]
78pub 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)]
93pub enum SecPreferencesDomain {
94    User = 0,
95    System = 1,
96    Common = 2,
97    Dynamic = 3,
98}
99
100extern "C" {
101    pub fn SecKeychainGetTypeID() -> CFTypeID;
102    pub fn SecKeychainCopyDefault(keychain: *mut SecKeychainRef) -> OSStatus;
103    pub fn SecKeychainCopyDomainDefault(
104        domain: SecPreferencesDomain,
105        keychain: *mut SecKeychainRef,
106    ) -> OSStatus;
107    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;
115    pub fn SecKeychainOpen(pathName: *const c_char, keychain: *mut SecKeychainRef) -> OSStatus;
116    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")]
123    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")]
135    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")]
154    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")]
166    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
184    pub fn SecKeychainSetSettings(
185        keychain: SecKeychainRef,
186        newSettings: *const SecKeychainSettings,
187    ) -> OSStatus;
188
189    #[cfg(target_os = "macos")]
190    pub fn SecKeychainGetUserInteractionAllowed(state: *mut Boolean) -> OSStatus;
191
192    #[cfg(target_os = "macos")]
193    pub fn SecKeychainSetUserInteractionAllowed(state: Boolean) -> OSStatus;
194}