sasl2_sys/
sasl.rs

1// Copyright Materialize, Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License in the LICENSE file at the
6// root of this repository, or online at
7//
8//     http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16//! Main SASL API.
17
18use libc::{c_char, c_int, c_uchar, c_uint, c_ulong, c_void};
19
20use super::prop::propctx;
21
22// Version.
23
24// Hack: decode version components from environment variables, where they
25// are encoded as single bytes. `u8::parse` is not yet a `const fn`, but
26// indexing into a byte slice is.
27const fn decode_version(s: &str) -> u8 {
28    s.as_bytes()[0]
29}
30
31// Hack: these `const fn`s work around a bug in ctest, which gets confused
32// about the `env!` expansion otherwise.
33
34const fn sasl_version_major() -> u8 {
35    decode_version(env!("SASL_VERSION_MAJOR"))
36}
37
38const fn sasl_version_minor() -> u8 {
39    decode_version(env!("SASL_VERSION_MINOR"))
40}
41
42const fn sasl_version_step() -> u8 {
43    decode_version(env!("SASL_VERSION_STEP"))
44}
45
46pub const SASL_VERSION_MAJOR: u8 = sasl_version_major();
47pub const SASL_VERSION_MINOR: u8 = sasl_version_minor();
48pub const SASL_VERSION_STEP: u8 = sasl_version_step();
49
50pub const SASL_VERSION_FULL: c_int = (SASL_VERSION_MAJOR as c_int) << 16
51    | (SASL_VERSION_MINOR as c_int) << 8
52    | SASL_VERSION_STEP as c_int;
53
54// Result codes.
55
56pub const SASL_CONTINUE: c_int = 1;
57pub const SASL_OK: c_int = 0;
58pub const SASL_FAIL: c_int = -1;
59pub const SASL_NOMEM: c_int = -2;
60pub const SASL_BUFOVER: c_int = -3;
61pub const SASL_NOMECH: c_int = -4;
62pub const SASL_BADPROT: c_int = -5;
63pub const SASL_NOTDONE: c_int = -6;
64pub const SASL_BADPARAM: c_int = -7;
65pub const SASL_TRYAGAIN: c_int = -8;
66pub const SASL_BADMAC: c_int = -9;
67pub const SASL_NOTINIT: c_int = -12;
68
69pub const SASL_INTERACT: c_int = 2;
70pub const SASL_BADSERV: c_int = -10;
71pub const SASL_WRONGMECH: c_int = -11;
72
73pub const SASL_BADAUTH: c_int = -13;
74pub const SASL_NOAUTHZ: c_int = -14;
75pub const SASL_TOOWEAK: c_int = -15;
76pub const SASL_ENCRYPT: c_int = -16;
77pub const SASL_TRANS: c_int = -17;
78
79pub const SASL_EXPIRED: c_int = -18;
80pub const SASL_DISABLED: c_int = -19;
81pub const SASL_NOUSER: c_int = -20;
82pub const SASL_BADVERS: c_int = -23;
83pub const SASL_UNAVAIL: c_int = -24;
84pub const SASL_NOVERIFY: c_int = -26;
85
86pub const SASL_PWLOCK: c_int = -21;
87pub const SASL_NOCHANGE: c_int = -22;
88pub const SASL_WEAKPASS: c_int = -27;
89pub const SASL_NOUSERPASS: c_int = -28;
90pub const SASL_NEED_OLD_PASSWD: c_int = -29;
91pub const SASL_CONSTRAINT_VIOLAT: c_int = -30;
92
93pub const SASL_BADBINDING: c_int = -32;
94
95pub const SASL_MECHNAMEMAX: c_int = 20;
96
97#[cfg(unix)]
98pub use libc::iovec;
99
100#[cfg(windows)]
101#[repr(C)]
102#[derive(Debug, Copy, Clone)]
103pub struct iovec {
104    pub iov_len: libc::c_long,
105    pub iov_base: *mut libc::c_char,
106}
107
108// Connection state.
109
110#[repr(C)]
111#[derive(Debug, Copy, Clone)]
112pub struct sasl_conn {
113    _unused: [u8; 0],
114}
115
116pub type sasl_conn_t = sasl_conn;
117
118// Password state.
119
120#[repr(C)]
121#[derive(Debug)]
122pub struct sasl_secret {
123    pub len: c_ulong,
124    pub data: [c_uchar; 1],
125}
126
127pub type sasl_secret_t = sasl_secret;
128
129// Random state.
130
131#[repr(C)]
132#[derive(Debug, Copy, Clone)]
133pub struct sasl_rand_s {
134    _unused: [u8; 0],
135}
136
137pub type sasl_rand_t = sasl_rand_s;
138
139// Memory allocation functions.
140
141pub type sasl_malloc_t = Option<unsafe extern "C" fn(arg1: usize) -> *mut c_void>;
142pub type sasl_calloc_t = Option<unsafe extern "C" fn(arg1: usize, arg2: usize) -> *mut c_void>;
143pub type sasl_realloc_t =
144    Option<unsafe extern "C" fn(arg1: *mut c_void, arg2: usize) -> *mut c_void>;
145pub type sasl_free_t = Option<unsafe extern "C" fn(arg1: *mut c_void)>;
146
147extern "C" {
148    pub fn sasl_set_alloc(
149        arg1: sasl_malloc_t,
150        arg2: sasl_calloc_t,
151        arg3: sasl_realloc_t,
152        arg4: sasl_free_t,
153    );
154}
155
156// Mutex functions.
157
158pub type sasl_mutex_alloc_t = Option<unsafe extern "C" fn() -> *mut c_void>;
159pub type sasl_mutex_lock_t = Option<unsafe extern "C" fn(mutex: *mut c_void) -> c_int>;
160pub type sasl_mutex_unlock_t = Option<unsafe extern "C" fn(mutex: *mut c_void) -> c_int>;
161pub type sasl_mutex_free_t = Option<unsafe extern "C" fn(mutex: *mut c_void)>;
162
163extern "C" {
164    pub fn sasl_set_mutex(
165        arg1: sasl_mutex_alloc_t,
166        arg2: sasl_mutex_lock_t,
167        arg3: sasl_mutex_unlock_t,
168        arg4: sasl_mutex_free_t,
169    );
170}
171
172// Security preference types.
173
174pub type sasl_ssf_t = c_uint;
175
176// Usage flags.
177
178pub const SASL_SUCCESS_DATA: c_uint = 4;
179pub const SASL_NEED_PROXY: c_uint = 8;
180pub const SASL_NEED_HTTP: c_uint = 16;
181
182// Security property types.
183
184pub const SASL_SEC_NOPLAINTEXT: c_uint = 1;
185pub const SASL_SEC_NOACTIVE: c_uint = 2;
186pub const SASL_SEC_NODICTIONARY: c_uint = 4;
187pub const SASL_SEC_FORWARD_SECRECY: c_uint = 8;
188pub const SASL_SEC_NOANONYMOUS: c_uint = 16;
189pub const SASL_SEC_PASS_CREDENTIALS: c_uint = 32;
190pub const SASL_SEC_MUTUAL_AUTH: c_uint = 64;
191#[cfg(not(all(target_os = "macos", not(feature = "vendored"))))]
192pub const SASL_SEC_MAXIMUM: c_uint = if SASL_VERSION_STEP == 28 { 65535 } else { 255 };
193#[cfg(all(target_os = "macos", not(feature = "vendored")))]
194pub const SASL_SEC_MAXIMUM: c_uint = 65535;
195
196#[repr(C)]
197#[derive(Debug, Copy, Clone)]
198pub struct sasl_security_properties {
199    pub min_ssf: sasl_ssf_t,
200    pub max_ssf: sasl_ssf_t,
201    pub maxbufsize: c_uint,
202    pub security_flags: c_uint,
203    pub property_names: *mut *const c_char,
204    pub property_values: *mut *const c_char,
205}
206
207pub type sasl_security_properties_t = sasl_security_properties;
208
209// Callbacks.
210
211#[repr(C)]
212#[derive(Debug, Copy, Clone)]
213pub struct sasl_callback {
214    pub id: c_ulong,
215    pub proc_: Option<unsafe extern "C" fn() -> c_int>,
216    pub context: *mut c_void,
217}
218
219pub type sasl_callback_t = sasl_callback;
220
221pub const SASL_CB_LIST_END: c_ulong = 0;
222
223pub type sasl_getopt_t = Option<
224    unsafe extern "C" fn(
225        context: *mut c_void,
226        plugin_name: *const c_char,
227        option: *const c_char,
228        result: *mut *const c_char,
229        len: *mut c_uint,
230    ) -> c_int,
231>;
232
233pub const SASL_CB_GETOPT: c_ulong = 1;
234
235pub const SASL_LOG_NONE: c_int = 0;
236pub const SASL_LOG_ERR: c_int = 1;
237pub const SASL_LOG_FAIL: c_int = 2;
238pub const SASL_LOG_WARN: c_int = 3;
239pub const SASL_LOG_NOTE: c_int = 4;
240pub const SASL_LOG_DEBUG: c_int = 5;
241pub const SASL_LOG_TRACE: c_int = 6;
242pub const SASL_LOG_PASS: c_int = 7;
243
244pub type sasl_log_t = Option<
245    unsafe extern "C" fn(context: *mut c_void, level: c_int, message: *const c_char) -> c_int,
246>;
247
248pub const SASL_CB_LOG: c_ulong = 2;
249
250pub type sasl_getpath_t =
251    Option<unsafe extern "C" fn(context: *mut c_void, path: *mut *const c_char) -> c_int>;
252
253pub const SASL_CB_GETPATH: c_ulong = 3;
254
255pub type sasl_verify_type_t = c_uint;
256
257pub const SASL_VRFY_PLUGIN: sasl_verify_type_t = 0;
258pub const SASL_VRFY_CONF: sasl_verify_type_t = 1;
259pub const SASL_VRFY_PASSWD: sasl_verify_type_t = 2;
260pub const SASL_VRFY_OTHER: sasl_verify_type_t = 3;
261
262pub type sasl_verifyfile_t = Option<
263    unsafe extern "C" fn(
264        context: *mut c_void,
265        file: *const c_char,
266        type_: sasl_verify_type_t,
267    ) -> c_int,
268>;
269
270pub const SASL_CB_VERIFYFILE: c_ulong = 4;
271
272pub type sasl_getconfpath_t =
273    Option<unsafe extern "C" fn(context: *mut c_void, path: *mut *mut c_char) -> c_int>;
274
275pub const SASL_CB_GETCONFPATH: c_ulong = 5;
276
277pub type sasl_getsimple_t = Option<
278    unsafe extern "C" fn(
279        context: *mut c_void,
280        id: c_int,
281        result: *mut *const c_char,
282        len: *mut c_uint,
283    ) -> c_int,
284>;
285
286pub const SASL_CB_USER: c_ulong = 16385;
287pub const SASL_CB_AUTHNAME: c_ulong = 16386;
288pub const SASL_CB_LANGUAGE: c_ulong = 16387;
289pub const SASL_CB_CNONCE: c_ulong = 16391;
290
291pub type sasl_getsecret_t = Option<
292    unsafe extern "C" fn(
293        conn: *mut sasl_conn_t,
294        context: *mut c_void,
295        id: c_int,
296        psecret: *mut *mut sasl_secret_t,
297    ) -> c_int,
298>;
299
300pub const SASL_CB_PASS: c_ulong = 16388;
301
302pub type sasl_chalprompt_t = Option<
303    unsafe extern "C" fn(
304        context: *mut c_void,
305        id: c_int,
306        challenge: *const c_char,
307        prompt: *const c_char,
308        defresult: *const c_char,
309        result: *mut *const c_char,
310        len: *mut c_uint,
311    ) -> c_int,
312>;
313
314pub const SASL_CB_ECHOPROMPT: c_ulong = 16389;
315pub const SASL_CB_NOECHOPROMPT: c_ulong = 16390;
316
317pub type sasl_getrealm_t = Option<
318    unsafe extern "C" fn(
319        context: *mut c_void,
320        id: c_int,
321        availrealms: *mut *const c_char,
322        result: *mut *const c_char,
323    ) -> c_int,
324>;
325
326pub const SASL_CB_GETREALM: c_ulong = 16392;
327
328pub type sasl_authorize_t = Option<
329    unsafe extern "C" fn(
330        conn: *mut sasl_conn_t,
331        context: *mut c_void,
332        requested_user: *const c_char,
333        rlen: c_uint,
334        auth_identity: *const c_char,
335        alen: c_uint,
336        def_realm: *const c_char,
337        urlen: c_uint,
338        propctx: *mut propctx,
339    ) -> c_int,
340>;
341
342pub const SASL_CB_PROXY_POLICY: c_ulong = 32769;
343
344pub type sasl_server_userdb_checkpass_t = Option<
345    unsafe extern "C" fn(
346        conn: *mut sasl_conn_t,
347        context: *mut c_void,
348        user: *const c_char,
349        pass: *const c_char,
350        passlen: c_uint,
351        propctx: *mut propctx,
352    ) -> c_int,
353>;
354
355pub const SASL_CB_SERVER_USERDB_CHECKPASS: c_ulong = 32773;
356
357pub type sasl_server_userdb_setpass_t = Option<
358    unsafe extern "C" fn(
359        conn: *mut sasl_conn_t,
360        context: *mut c_void,
361        user: *const c_char,
362        pass: *const c_char,
363        passlen: c_uint,
364        propctx: *mut propctx,
365        flags: c_uint,
366    ) -> c_int,
367>;
368
369pub const SASL_CB_SERVER_USERDB_SETPASS: c_ulong = 32774;
370
371pub const SASL_CU_NONE: c_uint = 0;
372pub const SASL_CU_AUTHID: c_uint = 1;
373pub const SASL_CU_AUTHZID: c_uint = 2;
374pub const SASL_CU_EXTERNALLY_VERIFIED: c_uint = 4;
375pub const SASL_CU_OVERRIDE: c_uint = 8;
376pub const SASL_CU_ASIS_MASK: c_uint = 65520;
377pub const SASL_CU_VERIFY_AGAINST_HASH: c_uint = 16;
378
379pub type sasl_canon_user_t = Option<
380    unsafe extern "C" fn(
381        conn: *mut sasl_conn_t,
382        context: *mut c_void,
383        in_: *const c_char,
384        inlen: c_uint,
385        flags: c_uint,
386        user_realm: *const c_char,
387        out: *mut c_char,
388        out_max: c_uint,
389        out_len: *mut c_uint,
390    ) -> c_int,
391>;
392
393pub const SASL_CB_CANON_USER: c_ulong = 32775;
394
395// Common client/server functions.
396
397pub const SASL_PATH_TYPE_PLUGIN: c_int = 0;
398pub const SASL_PATH_TYPE_CONFIG: c_int = 1;
399
400extern "C" {
401    pub fn sasl_set_path(path_type: c_int, path: *mut c_char) -> c_int;
402
403    pub fn sasl_version(implementation: *mut *const c_char, version: *mut c_int);
404
405    pub fn sasl_version_info(
406        implementation: *mut *const c_char,
407        version_string: *mut *const c_char,
408        version_major: *mut c_int,
409        version_minor: *mut c_int,
410        version_step: *mut c_int,
411        version_patch: *mut c_int,
412    );
413
414    pub fn sasl_done();
415
416    pub fn sasl_server_done() -> c_int;
417
418    pub fn sasl_client_done() -> c_int;
419
420    pub fn sasl_dispose(pconn: *mut *mut sasl_conn_t);
421
422    pub fn sasl_errstring(
423        saslerr: c_int,
424        langlist: *const c_char,
425        outlang: *mut *const c_char,
426    ) -> *const c_char;
427
428    pub fn sasl_errdetail(conn: *mut sasl_conn_t) -> *const c_char;
429
430    pub fn sasl_seterror(conn: *mut sasl_conn_t, flags: c_uint, fmt: *const c_char, ...);
431}
432
433pub const SASL_NOLOG: c_uint = 1;
434
435extern "C" {
436    pub fn sasl_getprop(
437        conn: *mut sasl_conn_t,
438        propnum: c_int,
439        pvalue: *mut *const c_void,
440    ) -> c_int;
441}
442
443pub const SASL_USERNAME: c_uint = 0;
444pub const SASL_SSF: c_uint = 1;
445pub const SASL_MAXOUTBUF: c_uint = 2;
446pub const SASL_DEFUSERREALM: c_uint = 3;
447pub const SASL_GETOPTCTX: c_uint = 4;
448pub const SASL_CALLBACK: c_uint = 7;
449pub const SASL_IPLOCALPORT: c_uint = 8;
450pub const SASL_IPREMOTEPORT: c_uint = 9;
451pub const SASL_PLUGERR: c_uint = 10;
452pub const SASL_DELEGATEDCREDS: c_uint = 11;
453pub const SASL_SERVICE: c_uint = 12;
454pub const SASL_SERVERFQDN: c_uint = 13;
455pub const SASL_AUTHSOURCE: c_uint = 14;
456pub const SASL_MECHNAME: c_uint = 15;
457pub const SASL_AUTHUSER: c_uint = 16;
458pub const SASL_APPNAME: c_uint = 17;
459pub const SASL_GSS_CREDS: c_uint = 18;
460pub const SASL_GSS_PEER_NAME: c_uint = 19;
461pub const SASL_GSS_LOCAL_NAME: c_uint = 20;
462
463#[repr(C)]
464#[derive(Debug, Copy, Clone)]
465pub struct sasl_channel_binding {
466    pub name: *const c_char,
467    pub critical: c_int,
468    pub len: c_ulong,
469    pub data: *const ::std::os::raw::c_uchar,
470}
471pub type sasl_channel_binding_t = sasl_channel_binding;
472
473pub const SASL_CHANNEL_BINDING: c_uint = 21;
474
475#[repr(C)]
476#[derive(Debug, Copy, Clone)]
477pub struct sasl_http_request {
478    pub method: *const c_char,
479    pub uri: *const c_char,
480    pub entity: *const ::std::os::raw::c_uchar,
481    pub elen: c_ulong,
482    pub non_persist: c_uint,
483}
484
485pub type sasl_http_request_t = sasl_http_request;
486
487pub const SASL_HTTP_REQUEST: c_uint = 22;
488
489extern "C" {
490    pub fn sasl_setprop(conn: *mut sasl_conn_t, propnum: c_int, value: *const c_void) -> c_int;
491}
492
493pub const SASL_SSF_EXTERNAL: c_uint = 100;
494pub const SASL_SEC_PROPS: c_uint = 101;
495pub const SASL_AUTH_EXTERNAL: c_uint = 102;
496
497extern "C" {
498    pub fn sasl_idle(conn: *mut sasl_conn_t) -> c_int;
499}
500
501// Client API.
502
503#[repr(C)]
504#[derive(Debug, Copy, Clone)]
505pub struct sasl_interact {
506    pub id: c_ulong,
507    pub challenge: *const c_char,
508    pub prompt: *const c_char,
509    pub defresult: *const c_char,
510    pub result: *const c_void,
511    pub len: c_uint,
512}
513
514pub type sasl_interact_t = sasl_interact;
515
516extern "C" {
517    pub fn sasl_client_init(callbacks: *const sasl_callback_t) -> c_int;
518
519    pub fn sasl_client_new(
520        service: *const c_char,
521        serverFQDN: *const c_char,
522        iplocalport: *const c_char,
523        ipremoteport: *const c_char,
524        prompt_supp: *const sasl_callback_t,
525        flags: c_uint,
526        pconn: *mut *mut sasl_conn_t,
527    ) -> c_int;
528
529    pub fn sasl_client_start(
530        conn: *mut sasl_conn_t,
531        mechlist: *const c_char,
532        prompt_need: *mut *mut sasl_interact_t,
533        clientout: *mut *const c_char,
534        clientoutlen: *mut c_uint,
535        mech: *mut *const c_char,
536    ) -> c_int;
537
538    pub fn sasl_client_step(
539        conn: *mut sasl_conn_t,
540        serverin: *const c_char,
541        serverinlen: c_uint,
542        prompt_need: *mut *mut sasl_interact_t,
543        clientout: *mut *const c_char,
544        clientoutlen: *mut c_uint,
545    ) -> c_int;
546}
547
548// Server API.
549
550extern "C" {
551    pub fn sasl_server_init(callbacks: *const sasl_callback_t, appname: *const c_char) -> c_int;
552
553    pub fn sasl_server_new(
554        service: *const c_char,
555        serverFQDN: *const c_char,
556        user_realm: *const c_char,
557        iplocalport: *const c_char,
558        ipremoteport: *const c_char,
559        callbacks: *const sasl_callback_t,
560        flags: c_uint,
561        pconn: *mut *mut sasl_conn_t,
562    ) -> c_int;
563
564    pub fn sasl_global_listmech() -> *mut *const c_char;
565
566    pub fn sasl_listmech(
567        conn: *mut sasl_conn_t,
568        user: *const c_char,
569        prefix: *const c_char,
570        sep: *const c_char,
571        suffix: *const c_char,
572        result: *mut *const c_char,
573        plen: *mut c_uint,
574        pcount: *mut c_int,
575    ) -> c_int;
576
577    pub fn sasl_server_start(
578        conn: *mut sasl_conn_t,
579        mech: *const c_char,
580        clientin: *const c_char,
581        clientinlen: c_uint,
582        serverout: *mut *const c_char,
583        serveroutlen: *mut c_uint,
584    ) -> c_int;
585
586    pub fn sasl_server_step(
587        conn: *mut sasl_conn_t,
588        clientin: *const c_char,
589        clientinlen: c_uint,
590        serverout: *mut *const c_char,
591        serveroutlen: *mut c_uint,
592    ) -> c_int;
593
594    pub fn sasl_checkapop(
595        conn: *mut sasl_conn_t,
596        challenge: *const c_char,
597        challen: c_uint,
598        response: *const c_char,
599        resplen: c_uint,
600    ) -> c_int;
601
602    pub fn sasl_checkpass(
603        conn: *mut sasl_conn_t,
604        user: *const c_char,
605        userlen: c_uint,
606        pass: *const c_char,
607        passlen: c_uint,
608    ) -> c_int;
609
610    pub fn sasl_user_exists(
611        conn: *mut sasl_conn_t,
612        service: *const c_char,
613        user_realm: *const c_char,
614        user: *const c_char,
615    ) -> c_int;
616
617    pub fn sasl_setpass(
618        conn: *mut sasl_conn_t,
619        user: *const c_char,
620        pass: *const c_char,
621        passlen: c_uint,
622        oldpass: *const c_char,
623        oldpasslen: c_uint,
624        flags: c_uint,
625    ) -> c_int;
626}
627
628pub const SASL_SET_CREATE: c_uint = 1;
629pub const SASL_SET_DISABLE: c_uint = 2;
630pub const SASL_SET_NOPLAIN: c_uint = 4;
631pub const SASL_SET_CURMECH_ONLY: c_uint = 8;
632
633// Auxilary property support.
634
635// TODO(benesch): these cause ctest to panic.
636// pub const SASL_AUX_ALL: &'static [u8; 2] = b"*\0";
637// pub const SASL_AUX_PASSWORD_PROP: &'static [u8; 13] = b"userPassword\0";
638// pub const SASL_AUX_PASSWORD: &'static [u8; 14] = b"*userPassword\0";
639// pub const SASL_AUX_UIDNUM: &'static [u8; 10] = b"uidNumber\0";
640// pub const SASL_AUX_GIDNUM: &'static [u8; 10] = b"gidNumber\0";
641// pub const SASL_AUX_FULLNAME: &'static [u8; 6] = b"gecos\0";
642// pub const SASL_AUX_HOMEDIR: &'static [u8; 14] = b"homeDirectory\0";
643// pub const SASL_AUX_SHELL: &'static [u8; 11] = b"loginShell\0";
644// pub const SASL_AUX_MAILADDR: &'static [u8; 5] = b"mail\0";
645// pub const SASL_AUX_UNIXMBX: &'static [u8; 17] = b"mailMessageStore\0";
646// pub const SASL_AUX_MAILCHAN: &'static [u8; 22] = b"mailSMTPSubmitChannel\0";
647
648extern "C" {
649    pub fn sasl_auxprop_request(conn: *mut sasl_conn_t, propnames: *mut *const c_char) -> c_int;
650
651    pub fn sasl_auxprop_getctx(conn: *mut sasl_conn_t) -> *mut propctx;
652
653    pub fn sasl_auxprop_store(
654        conn: *mut sasl_conn_t,
655        ctx: *mut propctx,
656        user: *const c_char,
657    ) -> c_int;
658}
659
660// Security layer.
661
662extern "C" {
663    pub fn sasl_encode(
664        conn: *mut sasl_conn_t,
665        input: *const c_char,
666        inputlen: c_uint,
667        output: *mut *const c_char,
668        outputlen: *mut c_uint,
669    ) -> c_int;
670
671    pub fn sasl_encodev(
672        conn: *mut sasl_conn_t,
673        invec: *const iovec,
674        numiov: c_uint,
675        output: *mut *const c_char,
676        outputlen: *mut c_uint,
677    ) -> c_int;
678
679    pub fn sasl_decode(
680        conn: *mut sasl_conn_t,
681        input: *const c_char,
682        inputlen: c_uint,
683        output: *mut *const c_char,
684        outputlen: *mut c_uint,
685    ) -> c_int;
686}