1 | diff --git a/Users/smichaud/Documents/ReverseEngineering/HookCase-master/HookLibraryTemplate/hook.mm b/hook.mm |
---|
2 | index e7102fb..d7e0fce 100644 |
---|
3 | --- a/Users/smichaud/Documents/ReverseEngineering/HookCase-master/HookLibraryTemplate/hook.mm |
---|
4 | +++ b/hook.mm |
---|
5 | @@ -1019,6 +1019,8 @@ loadHandler::loadHandler() |
---|
6 | LogWithFormat(true, "Hook.mm: loadHandler()"); |
---|
7 | PrintStackTrace(); |
---|
8 | #endif |
---|
9 | + |
---|
10 | + LogWithFormat(true, "Hook.mm: loadHandler()"); |
---|
11 | } |
---|
12 | |
---|
13 | loadHandler::~loadHandler() |
---|
14 | @@ -1200,6 +1202,748 @@ static int Hooked_interpose_example(char *arg1, int (*arg2)(char *)) |
---|
15 | |
---|
16 | // Put other hooked methods and swizzled classes here |
---|
17 | |
---|
18 | +typedef signed char INT1; /* 8 bits */ |
---|
19 | +typedef short INT2; /* 16 bits */ |
---|
20 | +typedef int INT4; /* 32 bits */ |
---|
21 | +/* There is no 64 bit type */ |
---|
22 | +typedef unsigned char UINT1; /* 8 bits */ |
---|
23 | +typedef unsigned short UINT2; /* 16 bits */ |
---|
24 | +typedef unsigned int UINT4; /* 32 bits */ |
---|
25 | +/* There is no 64 bit type */ |
---|
26 | + |
---|
27 | +#define NI_MAXHOST 1025 |
---|
28 | +#define NI_MAXSERV 32 |
---|
29 | + |
---|
30 | +#define CANON_BUF_SIZE 1024 |
---|
31 | + |
---|
32 | +enum Sasl_conn_type { SASL_CONN_UNKNOWN = 0, |
---|
33 | + SASL_CONN_SERVER = 1, |
---|
34 | + SASL_CONN_CLIENT = 2 }; |
---|
35 | + |
---|
36 | +/* security layer strength factor -- an unsigned integer usable by the caller |
---|
37 | + * to specify approximate security layer strength desired. Roughly |
---|
38 | + * correlated to effective key length for encryption. |
---|
39 | + * 0 = no protection |
---|
40 | + * 1 = integrity protection only |
---|
41 | + * 40 = 40-bit DES or 40-bit RC2/RC4 |
---|
42 | + * 56 = DES |
---|
43 | + * 112 = triple-DES |
---|
44 | + * 128 = 128-bit RC2/RC4/BLOWFISH |
---|
45 | + * 256 = baseline AES |
---|
46 | + */ |
---|
47 | +typedef unsigned sasl_ssf_t; |
---|
48 | + |
---|
49 | +#define SASL_CB_LIST_END 0 /* end of list */ |
---|
50 | +#define SASL_CB_GETOPT 1 |
---|
51 | +#define SASL_CB_LOG 2 |
---|
52 | +#define SASL_CB_GETPATH 3 |
---|
53 | +#define SASL_CB_VERIFYFILE 4 |
---|
54 | +#define SASL_CB_GETCONFPATH 5 |
---|
55 | +#define SASL_CB_USER 0x4001 /* client user identity to login as */ |
---|
56 | +#define SASL_CB_AUTHNAME 0x4002 /* client authentication name */ |
---|
57 | +#define SASL_CB_LANGUAGE 0x4003 /* comma separated list of RFC 1766 |
---|
58 | + * language codes in order of preference |
---|
59 | + * to be used to localize client prompts |
---|
60 | + * or server error codes */ |
---|
61 | +#define SASL_CB_CNONCE 0x4007 /* caller supplies client-nonce |
---|
62 | + * primarily for testing purposes */ |
---|
63 | +#define SASL_CB_PASS 0x4004 /* client passphrase-based secret */ |
---|
64 | +#define SASL_CB_ECHOPROMPT 0x4005 /* challenge and client enterred result */ |
---|
65 | +#define SASL_CB_NOECHOPROMPT 0x4006 /* challenge and client enterred result */ |
---|
66 | +#define SASL_CB_GETREALM (0x4008) /* realm to attempt authentication in */ |
---|
67 | +#define SASL_CB_PROXY_POLICY 0x8001 |
---|
68 | +#define SASL_CB_SERVER_USERDB_CHECKPASS (0x8005) |
---|
69 | +#define SASL_CB_SERVER_USERDB_SETPASS (0x8006) |
---|
70 | +#define SASL_CB_CANON_USER (0x8007) |
---|
71 | + |
---|
72 | +typedef struct buffer_info { |
---|
73 | + char *data; |
---|
74 | + size_t curlen; |
---|
75 | + size_t reallen; |
---|
76 | +} buffer_info_t; |
---|
77 | + |
---|
78 | +typedef struct sasl_callback { |
---|
79 | + /* Identifies the type of the callback function. |
---|
80 | + * Mechanisms must ignore callbacks with id's they don't recognize. |
---|
81 | + */ |
---|
82 | + unsigned long id; |
---|
83 | + int (*proc)(void); /* Callback function. Types of arguments vary by 'id' */ |
---|
84 | + void *context; |
---|
85 | +} sasl_callback_t; |
---|
86 | + |
---|
87 | +typedef struct { |
---|
88 | + const sasl_callback_t *callbacks; |
---|
89 | + const char *appname; |
---|
90 | +} sasl_global_callbacks_t; |
---|
91 | + |
---|
92 | +typedef struct sasl_out_params { |
---|
93 | + unsigned doneflag; /* exchange complete */ |
---|
94 | + |
---|
95 | + const char *user; /* canonicalized user name */ |
---|
96 | + const char *authid; /* canonicalized authentication id */ |
---|
97 | + |
---|
98 | + unsigned ulen; /* length of canonicalized user name */ |
---|
99 | + unsigned alen; /* length of canonicalized authid */ |
---|
100 | + |
---|
101 | + /* security layer information */ |
---|
102 | + unsigned maxoutbuf; /* Maximum buffer size, which will |
---|
103 | + produce buffer no bigger than the |
---|
104 | + negotiated SASL maximum buffer size */ |
---|
105 | + sasl_ssf_t mech_ssf; /* Should be set non-zero if negotiation of a |
---|
106 | + * security layer was *attempted*, even if |
---|
107 | + * the negotiation failed */ |
---|
108 | + void *encode_context; |
---|
109 | + int (*encode)(void *context, const struct iovec *invec, unsigned numiov, |
---|
110 | + const char **output, unsigned *outputlen); |
---|
111 | + void *decode_context; |
---|
112 | + int (*decode)(void *context, const char *input, unsigned inputlen, |
---|
113 | + const char **output, unsigned *outputlen); |
---|
114 | + |
---|
115 | + /* Pointer to delegated (client's) credentials, if supported by |
---|
116 | + the SASL mechanism */ |
---|
117 | + void *client_creds; |
---|
118 | + |
---|
119 | + /* for additions which don't require a version upgrade; set to 0 */ |
---|
120 | + const void *gss_peer_name; |
---|
121 | + const void *gss_local_name; |
---|
122 | + const char *cbindingname; /* channel binding name from packet */ |
---|
123 | + int (*spare_fptr1)(void); |
---|
124 | + int (*spare_fptr2)(void); |
---|
125 | + unsigned int cbindingdisp; /* channel binding disposition from client */ |
---|
126 | + int spare_int2; |
---|
127 | + int spare_int3; |
---|
128 | + int spare_int4; |
---|
129 | + |
---|
130 | + /* set to 0 initially, this allows a plugin with extended parameters |
---|
131 | + * to work with an older framework by updating version as parameters |
---|
132 | + * are added. |
---|
133 | + */ |
---|
134 | + int param_version; |
---|
135 | +} sasl_out_params_t; |
---|
136 | + |
---|
137 | +typedef struct _sasl_external_properties { |
---|
138 | + sasl_ssf_t ssf; |
---|
139 | + char *auth_id; |
---|
140 | +} _sasl_external_properties_t; |
---|
141 | + |
---|
142 | +typedef struct sasl_security_properties { |
---|
143 | + /* security strength factor |
---|
144 | + * min_ssf = minimum acceptable final level |
---|
145 | + * max_ssf = maximum acceptable final level |
---|
146 | + */ |
---|
147 | + sasl_ssf_t min_ssf; |
---|
148 | + sasl_ssf_t max_ssf; |
---|
149 | + |
---|
150 | + /* Maximum security layer receive buffer size. |
---|
151 | + * 0=security layer not supported |
---|
152 | + */ |
---|
153 | + unsigned maxbufsize; |
---|
154 | + |
---|
155 | + /* bitfield for attacks to protect against */ |
---|
156 | + unsigned security_flags; |
---|
157 | + |
---|
158 | + /* NULL terminated array of additional property names, values */ |
---|
159 | + const char **property_names; |
---|
160 | + const char **property_values; |
---|
161 | +} sasl_security_properties_t; |
---|
162 | + |
---|
163 | +typedef struct sasl_secret { |
---|
164 | + unsigned long len; |
---|
165 | + unsigned char data[1]; /* variable sized */ |
---|
166 | +} sasl_secret_t; |
---|
167 | + |
---|
168 | +typedef struct sasl_conn sasl_conn_t; |
---|
169 | + |
---|
170 | +struct sasl_conn { |
---|
171 | + enum Sasl_conn_type type; |
---|
172 | + |
---|
173 | + void (*destroy_conn)(sasl_conn_t *); /* destroy function */ |
---|
174 | + |
---|
175 | + char *service; |
---|
176 | + |
---|
177 | + unsigned int flags; /* flags passed to sasl_*_new */ |
---|
178 | + |
---|
179 | + /* IP information. A buffer of size 52 is adequate for this in its |
---|
180 | + longest format (see sasl.h) */ |
---|
181 | + int got_ip_local, got_ip_remote; |
---|
182 | + char iplocalport[NI_MAXHOST + NI_MAXSERV]; |
---|
183 | + char ipremoteport[NI_MAXHOST + NI_MAXSERV]; |
---|
184 | + |
---|
185 | + void *context; |
---|
186 | + sasl_out_params_t oparams; |
---|
187 | + |
---|
188 | + sasl_security_properties_t props; |
---|
189 | + _sasl_external_properties_t external; |
---|
190 | + |
---|
191 | + sasl_secret_t *secret; |
---|
192 | + |
---|
193 | + int (*idle_hook)(sasl_conn_t *conn); |
---|
194 | + const sasl_callback_t *callbacks; |
---|
195 | + const sasl_global_callbacks_t *global_callbacks; /* global callbacks |
---|
196 | + * connection */ |
---|
197 | + char *serverFQDN; |
---|
198 | + |
---|
199 | + /* Pointers to memory that we are responsible for */ |
---|
200 | + buffer_info_t *encode_buf; |
---|
201 | + |
---|
202 | + int error_code; |
---|
203 | + char *error_buf, *errdetail_buf; |
---|
204 | + size_t error_buf_len, errdetail_buf_len; |
---|
205 | + char *mechlist_buf; |
---|
206 | + size_t mechlist_buf_len; |
---|
207 | + |
---|
208 | + char *decode_buf; |
---|
209 | + |
---|
210 | + char user_buf[CANON_BUF_SIZE+1], authid_buf[CANON_BUF_SIZE+1]; |
---|
211 | + |
---|
212 | + /* Allocated by sasl_encodev if the output contains multiple SASL packet. */ |
---|
213 | + buffer_info_t multipacket_encoded_data; |
---|
214 | +}; |
---|
215 | + |
---|
216 | +typedef struct sasl_rand_s sasl_rand_t; |
---|
217 | + |
---|
218 | +typedef int sasl_getopt_t(void *context, const char *plugin_name, |
---|
219 | + const char *option, |
---|
220 | + const char **result, unsigned *len); |
---|
221 | + |
---|
222 | +typedef void *sasl_malloc_t(size_t); |
---|
223 | +typedef void *sasl_calloc_t(size_t, size_t); |
---|
224 | +typedef void *sasl_realloc_t(void *, size_t); |
---|
225 | +typedef void sasl_free_t(void *); |
---|
226 | + |
---|
227 | +typedef void *sasl_mutex_alloc_t(void); |
---|
228 | +typedef int sasl_mutex_lock_t(void *mutex); |
---|
229 | +typedef int sasl_mutex_unlock_t(void *mutex); |
---|
230 | +typedef void sasl_mutex_free_t(void *mutex); |
---|
231 | + |
---|
232 | +/* MD5 context. */ |
---|
233 | +typedef struct { |
---|
234 | + UINT4 state[4]; /* state (ABCD) */ |
---|
235 | + UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */ |
---|
236 | + unsigned char buffer[64]; /* input buffer */ |
---|
237 | +} MD5_CTX; |
---|
238 | + |
---|
239 | +typedef struct HMAC_MD5_CTX_s { |
---|
240 | + MD5_CTX ictx, octx; |
---|
241 | +} HMAC_MD5_CTX; |
---|
242 | + |
---|
243 | +typedef struct HMAC_MD5_STATE_s { |
---|
244 | + UINT4 istate[4]; |
---|
245 | + UINT4 ostate[4]; |
---|
246 | +} HMAC_MD5_STATE; |
---|
247 | + |
---|
248 | +typedef int (*sasl_callback_ft)(void); |
---|
249 | +typedef int sasl_getcallback_t(sasl_conn_t *conn, |
---|
250 | + unsigned long callbackid, |
---|
251 | + sasl_callback_ft * pproc, |
---|
252 | + void **pcontext); |
---|
253 | + |
---|
254 | +struct propctx; |
---|
255 | + |
---|
256 | +struct propval { |
---|
257 | + const char *name; /* name of property; NULL = end of list */ |
---|
258 | + /* same pointer used in request will be used here */ |
---|
259 | + const char **values; /* list of strings, values == NULL if property not |
---|
260 | + * found, *values == NULL if property found with |
---|
261 | + * no values */ |
---|
262 | + unsigned nvalues; /* total number of value strings */ |
---|
263 | + unsigned valsize; /* total size in characters of all value strings */ |
---|
264 | +}; |
---|
265 | + |
---|
266 | +typedef struct sasl_utils { |
---|
267 | + int version; |
---|
268 | + |
---|
269 | + /* contexts */ |
---|
270 | + sasl_conn_t *conn; |
---|
271 | + sasl_rand_t *rpool; |
---|
272 | + void *getopt_context; |
---|
273 | + |
---|
274 | + /* option function */ |
---|
275 | + sasl_getopt_t *getopt; |
---|
276 | + |
---|
277 | + /* allocation functions: */ |
---|
278 | + sasl_malloc_t *malloc; |
---|
279 | + sasl_calloc_t *calloc; |
---|
280 | + sasl_realloc_t *realloc; |
---|
281 | + sasl_free_t *free; |
---|
282 | + |
---|
283 | + /* mutex functions: */ |
---|
284 | + sasl_mutex_alloc_t *mutex_alloc; |
---|
285 | + sasl_mutex_lock_t *mutex_lock; |
---|
286 | + sasl_mutex_unlock_t *mutex_unlock; |
---|
287 | + sasl_mutex_free_t *mutex_free; |
---|
288 | + |
---|
289 | + /* MD5 hash and HMAC functions */ |
---|
290 | + void (*MD5Init)(MD5_CTX *); |
---|
291 | + void (*MD5Update)(MD5_CTX *, const unsigned char *text, unsigned int len); |
---|
292 | + void (*MD5Final)(unsigned char [16], MD5_CTX *); |
---|
293 | + void (*hmac_md5)(const unsigned char *text, int text_len, |
---|
294 | + const unsigned char *key, int key_len, |
---|
295 | + unsigned char [16]); |
---|
296 | + void (*hmac_md5_init)(HMAC_MD5_CTX *, const unsigned char *key, int len); |
---|
297 | + /* hmac_md5_update() is just a call to MD5Update on inner context */ |
---|
298 | + void (*hmac_md5_final)(unsigned char [16], HMAC_MD5_CTX *); |
---|
299 | + void (*hmac_md5_precalc)(HMAC_MD5_STATE *, |
---|
300 | + const unsigned char *key, int len); |
---|
301 | + void (*hmac_md5_import)(HMAC_MD5_CTX *, HMAC_MD5_STATE *); |
---|
302 | + |
---|
303 | + /* mechanism utility functions (same as above): */ |
---|
304 | + int (*mkchal)(sasl_conn_t *conn, char *buf, unsigned maxlen, |
---|
305 | + unsigned hostflag); |
---|
306 | + int (*utf8verify)(const char *str, unsigned len); |
---|
307 | + void (*rand)(sasl_rand_t *rpool, char *buf, unsigned len); |
---|
308 | + void (*churn)(sasl_rand_t *rpool, const char *data, unsigned len); |
---|
309 | + |
---|
310 | + /* This allows recursive calls to the sasl_checkpass() routine from |
---|
311 | + * within a SASL plug-in. This MUST NOT be used in the PLAIN mechanism |
---|
312 | + * as sasl_checkpass MAY be a front-end for the PLAIN mechanism. |
---|
313 | + * This is intended for use by the non-standard LOGIN mechanism and |
---|
314 | + * potentially by a future mechanism which uses public-key technology to |
---|
315 | + * set up a lightweight encryption layer just for sending a password. |
---|
316 | + */ |
---|
317 | + int (*checkpass)(sasl_conn_t *conn, |
---|
318 | + const char *user, unsigned userlen, |
---|
319 | + const char *pass, unsigned passlen); |
---|
320 | + |
---|
321 | + /* Access to base64 encode/decode routines */ |
---|
322 | + int (*decode64)(const char *in, unsigned inlen, |
---|
323 | + char *out, unsigned outmax, unsigned *outlen); |
---|
324 | + int (*encode64)(const char *in, unsigned inlen, |
---|
325 | + char *out, unsigned outmax, unsigned *outlen); |
---|
326 | + |
---|
327 | + /* erase a buffer */ |
---|
328 | + void (*erasebuffer)(char *buf, unsigned len); |
---|
329 | + |
---|
330 | + /* callback to sasl_getprop() and sasl_setprop() */ |
---|
331 | + int (*getprop)(sasl_conn_t *conn, int propnum, const void **pvalue); |
---|
332 | + int (*setprop)(sasl_conn_t *conn, int propnum, const void *value); |
---|
333 | + |
---|
334 | + /* callback function */ |
---|
335 | + sasl_getcallback_t *getcallback; |
---|
336 | + |
---|
337 | + /* format a message and then pass it to the SASL_CB_LOG callback |
---|
338 | + * |
---|
339 | + * use syslog()-style formatting (printf with %m as a human readable text |
---|
340 | + * (strerror()) for the error specified as the parameter). |
---|
341 | + * The implementation may use a fixed size buffer not smaller |
---|
342 | + * than 512 octets if it securely truncates the message. |
---|
343 | + * |
---|
344 | + * level is a SASL_LOG_* level (see sasl.h) |
---|
345 | + */ |
---|
346 | + void (*log)(sasl_conn_t *conn, int level, const char *fmt, ...) __attribute__((format(printf, 3, 4))); |
---|
347 | + |
---|
348 | + /* callback to sasl_seterror() */ |
---|
349 | + void (*seterror)(sasl_conn_t *conn, unsigned flags, const char *fmt, ...) __attribute__((format(printf, 3, 4))); |
---|
350 | + |
---|
351 | + /* spare function pointer */ |
---|
352 | + int *(*spare_fptr)(void); |
---|
353 | + |
---|
354 | + /* auxiliary property utilities */ |
---|
355 | + struct propctx *(*prop_new)(unsigned estimate); |
---|
356 | + int (*prop_dup)(struct propctx *src_ctx, struct propctx **dst_ctx); |
---|
357 | + int (*prop_request)(struct propctx *ctx, const char **names); |
---|
358 | + const struct propval *(*prop_get)(struct propctx *ctx); |
---|
359 | + int (*prop_getnames)(struct propctx *ctx, const char **names, |
---|
360 | + struct propval *vals); |
---|
361 | + void (*prop_clear)(struct propctx *ctx, int requests); |
---|
362 | + void (*prop_dispose)(struct propctx **ctx); |
---|
363 | + int (*prop_format)(struct propctx *ctx, const char *sep, int seplen, |
---|
364 | + char *outbuf, unsigned outmax, unsigned *outlen); |
---|
365 | + int (*prop_set)(struct propctx *ctx, const char *name, |
---|
366 | + const char *value, int vallen); |
---|
367 | + int (*prop_setvals)(struct propctx *ctx, const char *name, |
---|
368 | + const char **values); |
---|
369 | + void (*prop_erase)(struct propctx *ctx, const char *name); |
---|
370 | + int (*auxprop_store)(sasl_conn_t *conn, |
---|
371 | + struct propctx *ctx, const char *user); |
---|
372 | + |
---|
373 | + /* for additions which don't require a version upgrade; set to 0 */ |
---|
374 | + int (*spare_fptr1)(void); |
---|
375 | + int (*spare_fptr2)(void); |
---|
376 | +} sasl_utils_t; |
---|
377 | + |
---|
378 | +typedef struct sasl_channel_binding { |
---|
379 | + const char *name; |
---|
380 | + int critical; |
---|
381 | + unsigned long len; |
---|
382 | + const unsigned char *data; |
---|
383 | +} sasl_channel_binding_t; |
---|
384 | + |
---|
385 | +typedef struct sasl_http_request { |
---|
386 | + const char *method; /* HTTP Method */ |
---|
387 | + const char *uri; /* request-URI */ |
---|
388 | + const unsigned char *entity; /* entity-body */ |
---|
389 | + unsigned long elen; /* entity-body length */ |
---|
390 | + unsigned non_persist; /* Is it a non-persistent connection? */ |
---|
391 | +} sasl_http_request_t; |
---|
392 | + |
---|
393 | +typedef struct sasl_client_params { |
---|
394 | + const char *service; /* service name */ |
---|
395 | + const char *serverFQDN; /* server fully qualified domain name */ |
---|
396 | + const char *clientFQDN; /* client's fully qualified domain name */ |
---|
397 | + const sasl_utils_t *utils; /* SASL API utility routines -- |
---|
398 | + * for a particular sasl_conn_t, |
---|
399 | + * MUST remain valid until mech_free is |
---|
400 | + * called */ |
---|
401 | + const sasl_callback_t *prompt_supp; /* client callback list */ |
---|
402 | + const char *iplocalport; /* server IP domain literal & port */ |
---|
403 | + const char *ipremoteport; /* client IP domain literal & port */ |
---|
404 | + |
---|
405 | + unsigned servicelen; /* length of service */ |
---|
406 | + unsigned slen; /* length of serverFQDN */ |
---|
407 | + unsigned clen; /* length of clientFQDN */ |
---|
408 | + unsigned iploclen; /* length of iplocalport */ |
---|
409 | + unsigned ipremlen; /* length of ipremoteport */ |
---|
410 | + |
---|
411 | + /* application's security requirements & info */ |
---|
412 | + sasl_security_properties_t props; |
---|
413 | + sasl_ssf_t external_ssf; /* external SSF active */ |
---|
414 | + |
---|
415 | + /* for additions which don't require a version upgrade; set to 0 */ |
---|
416 | + const void *gss_creds; /* GSS credential handle */ |
---|
417 | + const sasl_channel_binding_t *cbinding; /* client channel binding */ |
---|
418 | + const sasl_http_request_t *http_request;/* HTTP Digest request method */ |
---|
419 | + void *spare_ptr4; |
---|
420 | + |
---|
421 | + /* Canonicalize a user name from on-wire to internal format |
---|
422 | + * added rjs3 2001-05-23 |
---|
423 | + * Must be called once user name aquired if canon_user is non-NULL. |
---|
424 | + * conn connection context |
---|
425 | + * in user name from wire protocol (need not be NUL terminated) |
---|
426 | + * len length of user name from wire protocol (0 = strlen(user)) |
---|
427 | + * flags for SASL_CU_* flags |
---|
428 | + * oparams the user, authid, ulen, alen, fields are |
---|
429 | + * set appropriately after canonicalization/copying and |
---|
430 | + * authorization of arguments |
---|
431 | + * |
---|
432 | + * responsible for setting user, ulen, authid, and alen in the oparams |
---|
433 | + * structure |
---|
434 | + * |
---|
435 | + * default behavior is to strip leading and trailing whitespace, as |
---|
436 | + * well as allocating space for and copying the parameters. |
---|
437 | + * |
---|
438 | + * results: |
---|
439 | + * SASL_OK -- success |
---|
440 | + * SASL_NOMEM -- out of memory |
---|
441 | + * SASL_BADPARAM -- invalid conn |
---|
442 | + * SASL_BADPROT -- invalid user/authid |
---|
443 | + */ |
---|
444 | + int (*canon_user)(sasl_conn_t *conn, |
---|
445 | + const char *in, unsigned len, |
---|
446 | + unsigned flags, |
---|
447 | + sasl_out_params_t *oparams); |
---|
448 | + |
---|
449 | + int (*spare_fptr1)(void); |
---|
450 | + |
---|
451 | + unsigned int cbindingdisp; |
---|
452 | + int spare_int2; |
---|
453 | + int spare_int3; |
---|
454 | + |
---|
455 | + /* flags field as passed to sasl_client_new */ |
---|
456 | + unsigned flags; |
---|
457 | + |
---|
458 | + /* set to 0 initially, this allows a plugin with extended parameters |
---|
459 | + * to work with an older framework by updating version as parameters |
---|
460 | + * are added. |
---|
461 | + */ |
---|
462 | + int param_version; |
---|
463 | +} sasl_client_params_t; |
---|
464 | + |
---|
465 | +typedef struct sasl_interact { |
---|
466 | + unsigned long id; /* same as client/user callback ID */ |
---|
467 | + const char *challenge; /* presented to user (e.g. OTP challenge) */ |
---|
468 | + const char *prompt; /* presented to user (e.g. "Username: ") */ |
---|
469 | + const char *defresult; /* default result string */ |
---|
470 | + const void *result; /* set to point to result */ |
---|
471 | + unsigned len; /* set to length of result */ |
---|
472 | +} sasl_interact_t; |
---|
473 | + |
---|
474 | +typedef struct sasl_client_plug { |
---|
475 | + /* mechanism name */ |
---|
476 | + const char *mech_name; |
---|
477 | + |
---|
478 | + /* best mech additional security layer strength factor */ |
---|
479 | + sasl_ssf_t max_ssf; |
---|
480 | + |
---|
481 | + /* best security flags, as defined in sasl_security_properties_t */ |
---|
482 | + unsigned security_flags; |
---|
483 | + |
---|
484 | + /* features of plugin */ |
---|
485 | + unsigned features; |
---|
486 | + |
---|
487 | + /* required prompt ids, NULL = user/pass only */ |
---|
488 | + const unsigned long *required_prompts; |
---|
489 | + |
---|
490 | + /* global state for mechanism */ |
---|
491 | + void *glob_context; |
---|
492 | + |
---|
493 | + /* create context for mechanism, using params supplied |
---|
494 | + * glob_context -- from above |
---|
495 | + * params -- params from sasl_client_new |
---|
496 | + * conn_context -- context for one connection |
---|
497 | + * returns: |
---|
498 | + * SASL_OK -- success |
---|
499 | + * SASL_NOMEM -- not enough memory |
---|
500 | + * SASL_WRONGMECH -- mech doesn't support security params |
---|
501 | + */ |
---|
502 | + int (*mech_new)(void *glob_context, |
---|
503 | + sasl_client_params_t *cparams, |
---|
504 | + void **conn_context); |
---|
505 | + |
---|
506 | + /* perform one step of exchange. NULL is passed for serverin on |
---|
507 | + * first step. |
---|
508 | + * returns: |
---|
509 | + * SASL_OK -- success |
---|
510 | + * SASL_INTERACT -- user interaction needed to fill in prompts |
---|
511 | + * SASL_BADPROT -- server protocol incorrect/cancelled |
---|
512 | + * SASL_BADSERV -- server failed mutual auth |
---|
513 | + */ |
---|
514 | + int (*mech_step)(void *conn_context, |
---|
515 | + sasl_client_params_t *cparams, |
---|
516 | + const char *serverin, |
---|
517 | + unsigned serverinlen, |
---|
518 | + sasl_interact_t **prompt_need, |
---|
519 | + const char **clientout, |
---|
520 | + unsigned *clientoutlen, |
---|
521 | + sasl_out_params_t *oparams); |
---|
522 | + |
---|
523 | + /* dispose of connection context from mech_new |
---|
524 | + */ |
---|
525 | + void (*mech_dispose)(void *conn_context, const sasl_utils_t *utils); |
---|
526 | + |
---|
527 | + /* free all global space used by mechanism |
---|
528 | + * mech_dispose must be called on all mechanisms first |
---|
529 | + */ |
---|
530 | + void (*mech_free)(void *glob_context, const sasl_utils_t *utils); |
---|
531 | + |
---|
532 | + /* perform precalculations during a network round-trip |
---|
533 | + * or idle period. conn_context may be NULL |
---|
534 | + * returns 1 if action taken, 0 if no action taken |
---|
535 | + */ |
---|
536 | + int (*idle)(void *glob_context, |
---|
537 | + void *conn_context, |
---|
538 | + sasl_client_params_t *cparams); |
---|
539 | + |
---|
540 | + /* for additions which don't require a version upgrade; set to 0 */ |
---|
541 | + int (*spare_fptr1)(void); |
---|
542 | + int (*spare_fptr2)(void); |
---|
543 | +} sasl_client_plug_t; |
---|
544 | + |
---|
545 | +typedef int sasl_client_plug_init_t(const sasl_utils_t *utils, |
---|
546 | + int max_version, |
---|
547 | + int *out_version, |
---|
548 | + sasl_client_plug_t **pluglist, |
---|
549 | + int *plugcount); |
---|
550 | + |
---|
551 | +typedef struct client_sasl_mechanism { |
---|
552 | + int version; |
---|
553 | + char *plugname; |
---|
554 | + const sasl_client_plug_t *plug; |
---|
555 | +} client_sasl_mechanism_t; |
---|
556 | + |
---|
557 | +typedef struct cmechanism { |
---|
558 | + client_sasl_mechanism_t m; |
---|
559 | + struct cmechanism *next; |
---|
560 | +} cmechanism_t; |
---|
561 | + |
---|
562 | +typedef struct sasl_client_conn { |
---|
563 | + sasl_conn_t base; /* parts common to server + client */ |
---|
564 | + |
---|
565 | + cmechanism_t *mech; |
---|
566 | + sasl_client_params_t *cparams; |
---|
567 | + |
---|
568 | + char *clientFQDN; |
---|
569 | + |
---|
570 | + cmechanism_t *mech_list; /* list of available mechanisms */ |
---|
571 | + int mech_length; /* number of available mechanisms */ |
---|
572 | +} sasl_client_conn_t; |
---|
573 | + |
---|
574 | +GET_SET_IN_FUNCS(_sasl_locate_entry) |
---|
575 | +GET_SET_IN_FUNCS(dlsym) |
---|
576 | + |
---|
577 | +#define FIX_MACPORTS_CYRUS_SASL_BUG 1 |
---|
578 | + |
---|
579 | +void *Hooked_dlsym(void* handle, const char* symbol) |
---|
580 | +{ |
---|
581 | + set_in_dlsym(true); |
---|
582 | + |
---|
583 | +#ifdef FIX_MACPORTS_CYRUS_SASL_BUG |
---|
584 | + if ((get_in_dlsym_count() == 1) && get_in__sasl_locate_entry()) { |
---|
585 | + if (symbol && (symbol[0]== '_')) { |
---|
586 | + ++symbol; |
---|
587 | + } |
---|
588 | + } |
---|
589 | +#endif |
---|
590 | + |
---|
591 | + void *retval = dlsym(handle, symbol); |
---|
592 | + |
---|
593 | + if ((get_in_dlsym_count() == 1) && get_in__sasl_locate_entry()) { |
---|
594 | + LogWithFormat(true, "Hook.mm: dlsym(): handle %p, symbol %s, returning %p", |
---|
595 | + handle, symbol, retval); |
---|
596 | + } |
---|
597 | + |
---|
598 | + set_in_dlsym(false); |
---|
599 | + return retval; |
---|
600 | +} |
---|
601 | + |
---|
602 | +int (*_sasl_locate_entry_caller)(void *library, const char *entryname, |
---|
603 | + void **entry_point) = NULL; |
---|
604 | + |
---|
605 | +int Hooked__sasl_locate_entry(void *library, const char *entryname, |
---|
606 | + void **entry_point) |
---|
607 | +{ |
---|
608 | + set_in__sasl_locate_entry(true); |
---|
609 | + |
---|
610 | + int retval = _sasl_locate_entry_caller(library, entryname, entry_point); |
---|
611 | + |
---|
612 | + LogWithFormat(true, "Hook.mm: _sasl_locate_entry(): library %p, entryname %s, entry_point %p, returning %i", |
---|
613 | + library, entryname ? entryname : "[null]", entry_point ? *entry_point : NULL, retval); |
---|
614 | + |
---|
615 | + set_in__sasl_locate_entry(false); |
---|
616 | + return retval; |
---|
617 | +} |
---|
618 | + |
---|
619 | +int (*_sasl_get_plugin_caller)(const char *file, |
---|
620 | + const sasl_callback_t *verifyfile_cb, |
---|
621 | + void **libraryptr) = NULL; |
---|
622 | + |
---|
623 | +int Hooked__sasl_get_plugin(const char *file, |
---|
624 | + const sasl_callback_t *verifyfile_cb, |
---|
625 | + void **libraryptr) |
---|
626 | +{ |
---|
627 | + int retval = _sasl_get_plugin_caller(file, verifyfile_cb, libraryptr); |
---|
628 | + |
---|
629 | + LogWithFormat(true, "Hook.mm: _sasl_get_plugin(): file %s, library %p, returning %i", |
---|
630 | + file ? file : "[null]", libraryptr ? *libraryptr : NULL, retval); |
---|
631 | + //PrintStackTrace(); |
---|
632 | + |
---|
633 | + return retval; |
---|
634 | +} |
---|
635 | + |
---|
636 | +int (*sasl_client_add_plugin_caller)(const char *plugname, |
---|
637 | + sasl_client_plug_init_t *entry_point) = NULL; |
---|
638 | + |
---|
639 | +int Hooked_sasl_client_add_plugin(const char *plugname, |
---|
640 | + sasl_client_plug_init_t *entry_point) |
---|
641 | +{ |
---|
642 | + int retval = sasl_client_add_plugin_caller(plugname, entry_point); |
---|
643 | + |
---|
644 | + LogWithFormat(true, "Hook.mm: sasl_client_add_plugin(): plugname %s, entry_point %p, returning %i", |
---|
645 | + plugname ? plugname : "[null]", entry_point, retval); |
---|
646 | + //PrintStackTrace(); |
---|
647 | + |
---|
648 | + return retval; |
---|
649 | +} |
---|
650 | + |
---|
651 | +int (*sasl_client_new_caller)(const char *service, |
---|
652 | + const char *serverFQDN, |
---|
653 | + const char *iplocalport, |
---|
654 | + const char *ipremoteport, |
---|
655 | + const sasl_callback_t *prompt_supp, |
---|
656 | + unsigned flags, |
---|
657 | + sasl_conn_t **pconn) = NULL; |
---|
658 | + |
---|
659 | +int Hooked_sasl_client_new(const char *service, |
---|
660 | + const char *serverFQDN, |
---|
661 | + const char *iplocalport, |
---|
662 | + const char *ipremoteport, |
---|
663 | + const sasl_callback_t *prompt_supp, |
---|
664 | + unsigned flags, |
---|
665 | + sasl_conn_t **pconn) |
---|
666 | +{ |
---|
667 | + int retval = sasl_client_new_caller(service, serverFQDN, |
---|
668 | + iplocalport, ipremoteport, |
---|
669 | + prompt_supp, flags, pconn); |
---|
670 | + |
---|
671 | + LogWithFormat(true, "Hook.mm: sasl_client_new(1): service %s, serverFQDN %s, iplocalport %s, ipremoteport %s, flags 0x%x, returning %i", |
---|
672 | + service ? service : "[null]", serverFQDN ? serverFQDN : "[null]", |
---|
673 | + iplocalport ? iplocalport : "[null]", ipremoteport ? ipremoteport : "[null]", |
---|
674 | + flags, retval); |
---|
675 | + |
---|
676 | + sasl_getopt_t *getopt = NULL; |
---|
677 | + void *context = NULL; |
---|
678 | + for (const sasl_callback_t *callback = prompt_supp; callback->id != SASL_CB_LIST_END; ++callback) { |
---|
679 | + LogWithFormat(false, " prompt_supp id 0x%lx, proc %p, context %p", |
---|
680 | + callback->id, callback->proc, callback->context); |
---|
681 | + if (callback->id == SASL_CB_GETOPT) { |
---|
682 | + getopt = (sasl_getopt_t *) callback->proc; |
---|
683 | + context = callback->context; |
---|
684 | + } |
---|
685 | + } |
---|
686 | + |
---|
687 | + const char *client_mech_list = NULL; |
---|
688 | + if (getopt) { |
---|
689 | + getopt(context, NULL, "client_mech_list", &client_mech_list, NULL); |
---|
690 | + } |
---|
691 | + LogWithFormat(true, "Hook.mm: sasl_client_new(2): client_mech_list %s", |
---|
692 | + client_mech_list ? client_mech_list : "[null]"); |
---|
693 | + |
---|
694 | + return retval; |
---|
695 | +} |
---|
696 | + |
---|
697 | +int (*sasl_client_start_caller)(sasl_conn_t *conn, |
---|
698 | + const char *mechlist, |
---|
699 | + sasl_interact_t **prompt_need, |
---|
700 | + const char **clientout, |
---|
701 | + unsigned *clientoutlen, |
---|
702 | + const char **mech) = NULL; |
---|
703 | + |
---|
704 | +int Hooked_sasl_client_start(sasl_conn_t *conn, |
---|
705 | + const char *mechlist, |
---|
706 | + sasl_interact_t **prompt_need, |
---|
707 | + const char **clientout, |
---|
708 | + unsigned *clientoutlen, |
---|
709 | + const char **mech) |
---|
710 | +{ |
---|
711 | + sasl_client_conn_t *c_conn = (sasl_client_conn_t *) conn; |
---|
712 | + |
---|
713 | + int retval = sasl_client_start_caller(conn, mechlist, prompt_need, |
---|
714 | + clientout, clientoutlen, mech); |
---|
715 | + |
---|
716 | + LogWithFormat(true, "Hook.mm: sasl_client_start(1): type %u, flags %x, props (min_ssf %u, max_ssf %u, security_flags 0x%x), external (ssf %u, auth_id %s), mechlist %s, returning 0x%x", |
---|
717 | + conn ? conn->type : -1, conn ? conn->flags : -1, |
---|
718 | + conn ? conn->props.min_ssf : -1, |
---|
719 | + conn ? conn->props.max_ssf : -1, |
---|
720 | + conn ? conn->props.security_flags : -1, |
---|
721 | + conn ? conn->external.ssf : -1, |
---|
722 | + conn ? (conn->external.auth_id ? conn->external.auth_id : "[null]") : "[null]", |
---|
723 | + mechlist ? mechlist : "[null]", |
---|
724 | + retval); |
---|
725 | + |
---|
726 | + cmechanism_t *conn_mechs = NULL; |
---|
727 | + int conn_mechs_length = 0; |
---|
728 | + if (c_conn) { |
---|
729 | + conn_mechs = c_conn->mech_list; |
---|
730 | + conn_mechs_length = c_conn->mech_length; |
---|
731 | + } |
---|
732 | + LogWithFormat(true, "Hook.mm: sasl_client_start(2): conn_mechs %p, conn_mechs_length %i", |
---|
733 | + conn_mechs, conn_mechs_length); |
---|
734 | + for (cmechanism_t *m = conn_mechs; m != NULL; m = m->next) { |
---|
735 | + LogWithFormat(false, " plugin mech_name %s", m->m.plug->mech_name); |
---|
736 | + } |
---|
737 | + |
---|
738 | + return retval; |
---|
739 | +} |
---|
740 | + |
---|
741 | +int (*_sasl_is_equal_mech_caller)(const char *req_mech, |
---|
742 | + const char *plug_mech, |
---|
743 | + size_t req_mech_len, |
---|
744 | + int *plus) = NULL; |
---|
745 | + |
---|
746 | +int Hooked__sasl_is_equal_mech(const char *req_mech, |
---|
747 | + const char *plug_mech, |
---|
748 | + size_t req_mech_len, |
---|
749 | + int *plus) |
---|
750 | +{ |
---|
751 | + int retval = _sasl_is_equal_mech_caller(req_mech, plug_mech, req_mech_len, plus); |
---|
752 | + |
---|
753 | + LogWithFormat(true, "Hook.mm: _sasl_is_equal_mech(): req_mech %s, plug_mech %s, req_mech_len %lu, plus %i, returning %i", |
---|
754 | + req_mech ? req_mech : "[null]", plug_mech ? plug_mech : "[null]", |
---|
755 | + req_mech_len, plus ? *plus : -1, retval); |
---|
756 | + |
---|
757 | + return retval; |
---|
758 | +} |
---|
759 | + |
---|
760 | #pragma mark - |
---|
761 | |
---|
762 | typedef struct _hook_desc { |
---|
763 | @@ -1232,6 +1976,14 @@ __attribute__((used)) static const hook_desc user_hooks[] |
---|
764 | INTERPOSE_FUNCTION(NSPushAutoreleasePool), |
---|
765 | PATCH_FUNCTION(__CFInitialize, /System/Library/Frameworks/CoreFoundation.framework/CoreFoundation), |
---|
766 | PATCH_FUNCTION(__CFGetConverter, /System/Library/Frameworks/CoreFoundation.framework/CoreFoundation), |
---|
767 | + |
---|
768 | + INTERPOSE_FUNCTION(dlsym), |
---|
769 | + PATCH_FUNCTION(_sasl_locate_entry, /opt/local/lib/libsasl2.3.dylib), |
---|
770 | + PATCH_FUNCTION(_sasl_get_plugin, /opt/local/lib/libsasl2.3.dylib), |
---|
771 | + PATCH_FUNCTION(sasl_client_add_plugin, /opt/local/lib/libsasl2.3.dylib), |
---|
772 | + PATCH_FUNCTION(sasl_client_new, /opt/local/lib/libsasl2.3.dylib), |
---|
773 | + PATCH_FUNCTION(sasl_client_start, /opt/local/lib/libsasl2.3.dylib), |
---|
774 | + PATCH_FUNCTION(_sasl_is_equal_mech, /opt/local/lib/libsasl2.3.dylib), |
---|
775 | }; |
---|
776 | |
---|
777 | // What follows are declarations of the CoreSymbolication APIs that we use to |
---|