void unit_test(void) { CFStringRef good_id = CFSTR("*****@*****.**"); CFStringRef bogus_id = CFSTR("*****@*****.**"); ODRecordRef record = NULL; ODNodeRef node = NULL; char jid[1024]; CFStringRef short_name = CFSTR("korver"); test_assert(! odkerb_has_foreign_realm("foo@bar")); test_assert(odkerb_has_foreign_realm("foo@bar@baz")); test_assert(odkerb_copy_user_record_with_alt_security_identity(bogus_id, &record) != 0); test_assert(odkerb_copy_user_record_with_alt_security_identity(good_id, &record) == 0); test_assert(record != 0); test_assert(odkerb_get_im_handle_with_user_record(record, CFSTR(kIMTypeJABBER), CFSTR("ichatserver.apple.com"), short_name, jid, sizeof(jid)) == 0); test_assert(strsame(jid, "*****@*****.**")); record = 0; CFStringRef config_record_name = odkerb_create_config_record_name(good_id); test_assert(odkerb_copy_search_node_with_config_record_name(config_record_name, &node) == 0); test_assert(node != 0); test_assert(odkerb_copy_user_record_with_short_name(short_name, node, &record) == 0); test_assert(record != 0); test_assert(odkerb_get_im_handle_with_user_record(record, CFSTR(kIMTypeJABBER), CFSTR("ichatserver.apple.com"), short_name, jid, sizeof(jid)) == 0); test_assert(strsame(jid, "*****@*****.**")); record = 0; node = 0; test_assert(odkerb_get_im_handle("[email protected]@SOMEWHERE.ORG", "ichatserver.apple.com", kIMTypeJABBER, jid, sizeof(jid)) == 0); test_assert(strsame(jid, "*****@*****.**")); test_assert(odkerb_get_im_handle("*****@*****.**", "ichatserver.apple.com", kIMTypeJABBER, jid, sizeof(jid)) == 0); test_assert(strsame(jid, "*****@*****.**")); test_assert(odkerb_get_im_handle("[email protected]@SOMEWHERE.ORG", "ichatserver.apple.com", kIMTypeJABBER, jid, sizeof(jid)) != 0); }
int main(int argc, char *argv[]) { int i; char jid[512]; int failure = 0; if (argc == 1) unit_test(); else { for (i = 1; i < argc; ++i) { if (odkerb_get_im_handle(argv[i], "ichatserver.apple.com", kIMTypeJABBER, jid, sizeof(jid)) == 0) fprintf(stderr, "%30s => %s\n", argv[i], jid); else { fprintf(stderr, "%s FAILED\n", argv[i]); ++failure; } } } return failure; }
static int _sx_sasl_canon_user(sasl_conn_t *conn, void *ctx, const char *user, unsigned ulen, unsigned flags, const char *user_realm, const char *out_user, unsigned out_umax, unsigned *out_ulen) { char *buf; char principal[3072]; char out_buf[3072]; // node(1023) + '@'(1) + domain/realm(1023) + '@'(1) + krb domain(1023) + '\0'(1) _sx_sasl_data_t sd = (_sx_sasl_data_t)ctx; char user_null_term[1024]; if (ulen > (sizeof(user_null_term)-1)) { _sx_debug(ZONE, "Got a SASL argument \"user\" that exceeds our maximum length, rejecting"); return SASL_BADAUTH; } // make a NULL terminated copy for ourself memcpy(user_null_term, user, ulen); user_null_term[ulen] = '\0'; sasl_getprop(conn, SASL_MECHNAME, (const void **) &buf); if (strncmp(buf, "GSSAPI", 7) == 0) { // Reformat the user argument for odkerb_get_im_handle // (Remove the default realm from string if necessary) char adjusted_user[1024]; char *s = strdup(user_null_term); if (s) { char *c = strsep(&s, "@"); if (c) { strlcpy(adjusted_user, c, sizeof(adjusted_user)); c = strsep(&s, "@"); if (c) { // should be the default realm - ignore c = strsep(&s, "@"); if (c) { // should be a foreign realm that we want to check strlcat(adjusted_user, "@", sizeof(adjusted_user)); strlcat(adjusted_user, c, sizeof(adjusted_user)); } } else { _sx_debug(ZONE, "Notice: unexpected format of SASL \"user\" argument: %s", user_null_term); } } else { _sx_debug(ZONE, "Error getting SASL argument \"user\""); free(s); return SASL_BADAUTH; } free(s); } else { _sx_debug(ZONE, "Error copying SASL argument \"user\""); return SASL_BADAUTH; } snprintf(principal, sizeof(principal), "%s@%s", adjusted_user, user_realm); if (odkerb_get_im_handle(principal, sd->stream->req_to, "JABBER:", out_buf, ((out_umax > sizeof(out_buf)) ? sizeof(out_buf) : out_umax)) == 0) { strlcpy(out_user, out_buf, out_umax); *out_ulen = strlen(out_user); _sx_debug(ZONE, "Got IM handle: %s for user %s, realm %s", out_buf, user_null_term, user_realm); } else { return SASL_BADAUTH; } } else if (strncmp(buf, "ANONYMOUS", 10) == 0) { sd->ctx->cb(sx_sasl_cb_GEN_AUTHZID, NULL, (void **)&buf, sd->stream, sd->ctx->cbarg); strncpy(out_user, buf, out_umax); out_user[out_umax]='\0'; *out_ulen=strlen(out_user); } else { memcpy(out_user,user,ulen); *out_ulen = ulen; } return SASL_OK; }