cloud_storage_account cloud_storage_account::parse(const utility::string_t& connection_string) { cloud_storage_account account; auto settings = parse_string_into_settings(connection_string); account = parse_devstore_settings(settings); if (account.is_initialized()) { get_credentials(settings); account.m_settings = settings; return account; } account = parse_defaults_settings(settings); if (account.is_initialized()) { get_credentials(settings); account.m_settings = settings; return account; } account = parse_explicit_settings(settings); if (account.is_initialized()) { get_credentials(settings); account.m_settings = settings; return account; } throw std::invalid_argument("connection_string"); }
/* Examine a Basic auth challenge. * Returns 0 if an valid challenge, else non-zero. */ static int basic_challenge(auth_session *sess, struct auth_challenge *parms) { char *tmp, password[NE_ABUFSIZ]; /* Verify challenge... must have a realm */ if (parms->realm == NULL) { return -1; } NE_DEBUG(NE_DBG_HTTPAUTH, "Got Basic challenge with realm [%s]\n", parms->realm); clean_session(sess); sess->realm = ne_strdup(parms->realm); if (get_credentials(sess, password)) { /* Failed to get credentials */ return -1; } sess->scheme = auth_scheme_basic; tmp = ne_concat(sess->username, ":", password, NULL); sess->basic = ne_base64((unsigned char *)tmp, strlen(tmp)); ne_free(tmp); /* Paranoia. */ memset(password, 0, sizeof password); return 0; }
int select_auth_param(str* res, select_t* s, struct sip_msg* msg) { int ret; struct hdr_field* hdr; dig_cred_t* cred; if ((s->n != 3 && s->n != 4) || (s->params[s->n - 1].type != SEL_PARAM_DIV)) return -1; ret = get_credentials(msg, s, &hdr); if (!hdr) return ret; cred = &((auth_body_t*)hdr->parsed)->digest; switch(s->params[s->n - 1].v.i) { case SEL_AUTH_USER: RETURN0_res(cred->username.user); case SEL_AUTH_DOMAIN: RETURN0_res(cred->username.domain); case SEL_AUTH_USERNAME: RETURN0_res(cred->username.whole); case SEL_AUTH_REALM: RETURN0_res(cred->realm); case SEL_AUTH_NONCE: RETURN0_res(cred->nonce); case SEL_AUTH_URI: RETURN0_res(cred->uri); case SEL_AUTH_CNONCE: RETURN0_res(cred->cnonce); case SEL_AUTH_NC: RETURN0_res(cred->nc); case SEL_AUTH_RESPONSE: RETURN0_res(cred->response); case SEL_AUTH_OPAQUE: RETURN0_res(cred->opaque); case SEL_AUTH_ALG: RETURN0_res(cred->alg.alg_str); case SEL_AUTH_QOP: RETURN0_res(cred->qop.qop_str); default: BUG("Unsupported digest credentials parameter in select\n"); return -1; } }
/* Examine a Basic auth challenge. * Returns 0 if an valid challenge, else non-zero. */ static int basic_challenge(http_auth_session *sess, struct http_auth_chall *parms) { char *tmp, *password; /* Verify challenge... must have a realm */ if (parms->realm == NULL) { return -1; } DEBUG(DEBUG_HTTPAUTH, "Got Basic challenge with realm [%s]\n", parms->realm); clean_session(sess); sess->unq_realm = shave_string(parms->realm, '"'); if (get_credentials(sess, &password)) { /* Failed to get credentials */ HTTP_FREE(sess->unq_realm); return -1; } sess->scheme = http_auth_scheme_basic; CONCAT3(tmp, sess->username, ":", password?password:""); sess->basic = base64(tmp); free(tmp); HTTP_FREE(password); return 0; }
int main() { char *username, *password; OSStatus result = get_credentials(&username, &password); if (result) { printf("Failed getting credentials from keychain.\n"); return 1; } sxxxxxxx_session *session; //sxxxxxxx_init(&session, username, password); sxxxxxxx_run(session, FALSE); return 0; }
int select_auth(str* res, select_t* s, struct sip_msg* msg) { struct hdr_field* hdr; if (s->n != 2 && s->params[1].type != SEL_PARAM_STR) return -1; if (s->params[0].type != SEL_PARAM_DIV) { BUG("Last parameter should have type DIV (converted)\n"); return -1; } hdr = get_credentials(msg, s); if (!hdr) return -1; RETURN0_res(hdr->body); }
static SmlSyncHdrPtr_t prvGetHeader(internals_t * internP) { SmlSyncHdrPtr_t headerP; headerP = smlAllocSyncHdr(); if (headerP) { set_pcdata_string(headerP->version, "1.2"); set_pcdata_string(headerP->proto, "DM/1.2"); set_pcdata_hex(headerP->sessionID, internP->session_id); set_pcdata_int(headerP->msgID, internP->message_id); set_pcdata_int(headerP->msgID, internP->message_id); set_pcdata_string(headerP->target->locURI, internP->account->server_uri); set_pcdata_string(headerP->source->locURI, internP->account->id); if (OMADM_SYNCML_ERROR_AUTHENTICATION_ACCEPTED != internP->clt_auth) { headerP->cred = get_credentials(internP->account->toServerCred); } headerP->meta = smlAllocPcdata(); if (headerP->meta) { SmlMetInfMetInfPtr_t metInfP; metInfP = smlAllocMetInfMetInf(); if (metInfP) { metInfP->maxmsgsize = smlString2Pcdata(PRV_MAX_MESSAGE_SIZE); headerP->meta->contentType = SML_PCDATA_EXTENSION; headerP->meta->extension = SML_EXT_METINF; headerP->meta->length = 0; headerP->meta->content = metInfP; } else { smlFreePcdata(headerP->meta); headerP->meta = NULL; } } } return headerP; }
cloud_storage_account cloud_storage_account::parse_explicit_settings(std::map<utility::string_t, utility::string_t> settings) { utility::string_t blob_endpoint; utility::string_t queue_endpoint; utility::string_t table_endpoint; get_setting(settings, blob_endpoint_setting_string, blob_endpoint); get_setting(settings, queue_endpoint_setting_string, queue_endpoint); get_setting(settings, table_endpoint_setting_string, table_endpoint); storage_credentials credentials(get_credentials(settings)); if (settings.empty() && (!blob_endpoint.empty() || !queue_endpoint.empty() || !table_endpoint.empty())) { return cloud_storage_account(credentials, blob_endpoint.empty() ? storage_uri() : storage_uri(web::http::uri(blob_endpoint)), queue_endpoint.empty() ? storage_uri() : storage_uri(web::http::uri(queue_endpoint)), table_endpoint.empty() ? storage_uri() : storage_uri(web::http::uri(table_endpoint))); } return cloud_storage_account(); }
/* Examine a digest challenge: return 0 if it is a valid Digest challenge, * else non-zero. */ static int digest_challenge(auth_session *sess, struct auth_challenge *parms) { struct ne_md5_ctx tmp; unsigned char tmp_md5[16]; char password[NE_ABUFSIZ]; /* Verify they've given us the right bits. */ if (parms->alg == auth_alg_unknown || (parms->alg == auth_alg_md5_sess && !parms->qop_auth) || parms->realm == NULL || parms->nonce == NULL) { NE_DEBUG(NE_DBG_HTTPAUTH, "Invalid challenge."); return -1; } if (parms->stale) { /* Just a stale response, don't need to get a new username/password */ NE_DEBUG(NE_DBG_HTTPAUTH, "Stale digest challenge.\n"); } else { /* Forget the old session details */ NE_DEBUG(NE_DBG_HTTPAUTH, "In digest challenge.\n"); clean_session(sess); sess->realm = ne_strdup(parms->realm); /* Not a stale response: really need user authentication */ if (get_credentials(sess, password)) { /* Failed to get credentials */ return -1; } } sess->alg = parms->alg; sess->scheme = auth_scheme_digest; sess->nonce = ne_strdup(parms->nonce); sess->cnonce = get_cnonce(); /* TODO: add domain handling. */ if (parms->opaque != NULL) { sess->opaque = ne_strdup(parms->opaque); /* don't strip the quotes */ } if (parms->got_qop) { /* What type of qop are we to apply to the message? */ NE_DEBUG(NE_DBG_HTTPAUTH, "Got qop directive.\n"); sess->nonce_count = 0; sess->qop = auth_qop_auth; } else { /* No qop at all/ */ sess->qop = auth_qop_none; } if (!parms->stale) { /* Calculate H(A1). * tmp = H(unq(username-value) ":" unq(realm-value) ":" passwd) */ NE_DEBUG(NE_DBG_HTTPAUTH, "Calculating H(A1).\n"); ne_md5_init_ctx(&tmp); ne_md5_process_bytes(sess->username, strlen(sess->username), &tmp); ne_md5_process_bytes(":", 1, &tmp); ne_md5_process_bytes(sess->realm, strlen(sess->realm), &tmp); ne_md5_process_bytes(":", 1, &tmp); ne_md5_process_bytes(password, strlen(password), &tmp); memset(password, 0, sizeof password); /* done with that. */ ne_md5_finish_ctx(&tmp, tmp_md5); if (sess->alg == auth_alg_md5_sess) { unsigned char a1_md5[16]; struct ne_md5_ctx a1; char tmp_md5_ascii[33]; /* Now we calculate the SESSION H(A1) * A1 = H(...above...) ":" unq(nonce-value) ":" unq(cnonce-value) */ ne_md5_to_ascii(tmp_md5, tmp_md5_ascii); ne_md5_init_ctx(&a1); ne_md5_process_bytes(tmp_md5_ascii, 32, &a1); ne_md5_process_bytes(":", 1, &a1); ne_md5_process_bytes(sess->nonce, strlen(sess->nonce), &a1); ne_md5_process_bytes(":", 1, &a1); ne_md5_process_bytes(sess->cnonce, strlen(sess->cnonce), &a1); ne_md5_finish_ctx(&a1, a1_md5); ne_md5_to_ascii(a1_md5, sess->h_a1); NE_DEBUG(NE_DBG_HTTPAUTH, "Session H(A1) is [%s]\n", sess->h_a1); } else { ne_md5_to_ascii(tmp_md5, sess->h_a1); NE_DEBUG(NE_DBG_HTTPAUTH, "H(A1) is [%s]\n", sess->h_a1); } } NE_DEBUG(NE_DBG_HTTPAUTH, "I like this Digest challenge.\n"); return 0; }
static NTSTATUS idmap_ldap_db_init(struct idmap_domain *dom) { NTSTATUS ret; struct idmap_ldap_context *ctx = NULL; char *config_option = NULL; const char *tmp = NULL; /* Only do init if we are online */ if (idmap_is_offline()) { return NT_STATUS_FILE_IS_OFFLINE; } ctx = talloc_zero(dom, struct idmap_ldap_context); if ( ! ctx) { DEBUG(0, ("Out of memory!\n")); return NT_STATUS_NO_MEMORY; } config_option = talloc_asprintf(ctx, "idmap config %s", dom->name); if (!config_option) { DEBUG(0, ("Out of memory!\n")); ret = NT_STATUS_NO_MEMORY; goto done; } tmp = lp_parm_const_string(-1, config_option, "ldap_url", NULL); if ( ! tmp) { DEBUG(1, ("ERROR: missing idmap ldap url\n")); ret = NT_STATUS_UNSUCCESSFUL; goto done; } ctx->url = talloc_strdup(ctx, tmp); trim_char(ctx->url, '\"', '\"'); tmp = lp_parm_const_string(-1, config_option, "ldap_base_dn", NULL); if ( ! tmp || ! *tmp) { tmp = lp_ldap_idmap_suffix(talloc_tos()); if ( ! tmp) { DEBUG(1, ("ERROR: missing idmap ldap suffix\n")); ret = NT_STATUS_UNSUCCESSFUL; goto done; } } ctx->suffix = talloc_strdup(ctx, tmp); CHECK_ALLOC_DONE(ctx->suffix); ctx->rw_ops = talloc_zero(ctx, struct idmap_rw_ops); CHECK_ALLOC_DONE(ctx->rw_ops); ctx->rw_ops->get_new_id = idmap_ldap_allocate_id_internal; ctx->rw_ops->set_mapping = idmap_ldap_set_mapping; /* get_credentials deals with setting up creds */ ret = smbldap_init(ctx, winbind_event_context(), ctx->url, false, NULL, NULL, &ctx->smbldap_state); if (!NT_STATUS_IS_OK(ret)) { DEBUG(1, ("ERROR: smbldap_init (%s) failed!\n", ctx->url)); goto done; } ret = get_credentials( ctx, ctx->smbldap_state, config_option, dom, &ctx->user_dn ); if ( !NT_STATUS_IS_OK(ret) ) { DEBUG(1,("idmap_ldap_db_init: Failed to get connection " "credentials (%s)\n", nt_errstr(ret))); goto done; } /* * Set the destructor on the context, so that resources are * properly freed when the context is released. */ talloc_set_destructor(ctx, idmap_ldap_close_destructor); dom->private_data = ctx; ret = verify_idpool(dom); if (!NT_STATUS_IS_OK(ret)) { DEBUG(1, ("idmap_ldap_db_init: failed to verify ID pool (%s)\n", nt_errstr(ret))); goto done; } talloc_free(config_option); return NT_STATUS_OK; /*failed */ done: talloc_free(ctx); return ret; }
/***************************************************************************** * Open: Initialize module's data structures and libdsm *****************************************************************************/ static int Open( vlc_object_t *p_this ) { access_t *p_access = (access_t*)p_this; access_sys_t *p_sys; smb_stat st; /* Init p_access */ access_InitFields( p_access ); p_sys = p_access->p_sys = (access_sys_t*)calloc( 1, sizeof( access_sys_t ) ); if( p_access->p_sys == NULL ) return VLC_ENOMEM; p_sys->p_ns = netbios_ns_new(); if( p_sys->p_ns == NULL ) goto error; p_sys->p_session = smb_session_new(); if( p_sys->p_session == NULL ) goto error; vlc_UrlParse( &p_sys->url, p_access->psz_location ); get_credentials( p_access ); if( get_address( p_access ) != VLC_SUCCESS ) goto error; msg_Dbg( p_access, "Creds: username = %s, domain = %s", p_sys->creds.login, p_sys->creds.domain ); msg_Dbg( p_access, "Session: Host name = %s, ip = %s", p_sys->netbios_name, inet_ntoa( p_sys->addr ) ); /* Now that we have the required data, let's establish a session */ if( !smb_session_connect( p_sys->p_session, p_sys->netbios_name, p_sys->addr.s_addr, SMB_TRANSPORT_TCP ) ) { msg_Err( p_access, "Unable to connect/negotiate SMB session"); goto error; } get_path( p_access ); if( login( p_access ) != VLC_SUCCESS ) { msg_Err( p_access, "Unable to connect to share %s", p_sys->psz_share ); goto error; } /* If there is no shares, browse them */ if( !p_sys->psz_share ) return BrowserInit( p_access ); msg_Dbg( p_access, "Path: Share name = %s, path = %s", p_sys->psz_share, p_sys->psz_path ); /* Let's finally ask a handle to the file we wanna read ! */ p_sys->i_fd = smb_fopen( p_sys->p_session, p_sys->i_tid, p_sys->psz_path, SMB_MOD_RO ); if( !p_sys->i_fd ) { msg_Err( p_access, "Unable to open file with path %s (in share %s)", p_sys->psz_path, p_sys->psz_share ); goto error; } st = smb_stat_fd( p_sys->p_session, p_sys->i_fd ); if( smb_stat_get( st, SMB_STAT_ISDIR ) ) { smb_fclose( p_sys->p_session, p_sys->i_fd ); return BrowserInit( p_access ); } msg_Dbg( p_access, "Successfully opened smb://%s", p_access->psz_location ); ACCESS_SET_CALLBACKS( Read, NULL, Control, Seek ); return VLC_SUCCESS; error: Close( p_this ); return VLC_EGENERIC; }
/* Examine a digest challenge: return 0 if it is a valid Digest challenge, * else non-zero. */ static int digest_challenge(http_auth_session *sess, struct http_auth_chall *parms) { struct md5_ctx tmp; unsigned char tmp_md5[16]; char *password; /* Do we understand this challenge? */ if (parms->alg == http_auth_alg_unknown) { DEBUG(DEBUG_HTTPAUTH, "Unknown algorithm.\n"); return -1; } if ((parms->alg == http_auth_alg_md5_sess) && !(parms->qop_auth || parms->qop_auth_int)) { DEBUG(DEBUG_HTTPAUTH, "Server did not give qop with MD5-session alg.\n"); return -1; } if ((parms->realm==NULL) || (parms->nonce==NULL)) { DEBUG(DEBUG_HTTPAUTH, "Challenge missing nonce or realm.\n"); return -1; } if (parms->stale) { /* Just a stale response, don't need to get a new username/password */ DEBUG(DEBUG_HTTPAUTH, "Stale digest challenge.\n"); } else { /* Forget the old session details */ DEBUG(DEBUG_HTTPAUTH, "In digest challenge.\n"); clean_session(sess); sess->unq_realm = shave_string(parms->realm, '"'); /* Not a stale response: really need user authentication */ if (get_credentials(sess, &password)) { /* Failed to get credentials */ HTTP_FREE(sess->unq_realm); return -1; } } sess->alg = parms->alg; sess->scheme = http_auth_scheme_digest; sess->unq_nonce = shave_string(parms->nonce, '"'); sess->unq_cnonce = get_cnonce(); if (parms->domain) { if (parse_domain(sess, parms->domain)) { /* TODO: Handle the error? */ } } else { sess->domain = NULL; sess->domain_count = 0; } if (parms->opaque != NULL) { sess->opaque = ne_strdup(parms->opaque); /* don't strip the quotes */ } if (parms->got_qop) { /* What type of qop are we to apply to the message? */ DEBUG(DEBUG_HTTPAUTH, "Got qop directive.\n"); sess->nonce_count = 0; if (parms->qop_auth_int) { sess->qop = http_auth_qop_auth_int; } else { sess->qop = http_auth_qop_auth; } } else { /* No qop at all/ */ sess->qop = http_auth_qop_none; } if (!parms->stale) { /* Calculate H(A1). * tmp = H(unq(username-value) ":" unq(realm-value) ":" passwd) */ DEBUG(DEBUG_HTTPAUTH, "Calculating H(A1).\n"); md5_init_ctx(&tmp); md5_process_bytes(sess->username, strlen(sess->username), &tmp); md5_process_bytes(":", 1, &tmp); md5_process_bytes(sess->unq_realm, strlen(sess->unq_realm), &tmp); md5_process_bytes(":", 1, &tmp); if (password != NULL) md5_process_bytes(password, strlen(password), &tmp); md5_finish_ctx(&tmp, tmp_md5); if (sess->alg == http_auth_alg_md5_sess) { unsigned char a1_md5[16]; struct md5_ctx a1; char tmp_md5_ascii[33]; /* Now we calculate the SESSION H(A1) * A1 = H(...above...) ":" unq(nonce-value) ":" unq(cnonce-value) */ md5_to_ascii(tmp_md5, tmp_md5_ascii); md5_init_ctx(&a1); md5_process_bytes(tmp_md5_ascii, 32, &a1); md5_process_bytes(":", 1, &a1); md5_process_bytes(sess->unq_nonce, strlen(sess->unq_nonce), &a1); md5_process_bytes(":", 1, &a1); md5_process_bytes(sess->unq_cnonce, strlen(sess->unq_cnonce), &a1); md5_finish_ctx(&a1, a1_md5); md5_to_ascii(a1_md5, sess->h_a1); DEBUG(DEBUG_HTTPAUTH, "Session H(A1) is [%s]\n", sess->h_a1); } else { md5_to_ascii(tmp_md5, sess->h_a1); DEBUG(DEBUG_HTTPAUTH, "H(A1) is [%s]\n", sess->h_a1); } HTTP_FREE(password); } DEBUG(DEBUG_HTTPAUTH, "I like this Digest challenge.\n"); return 0; }
static NTSTATUS idmap_ldap_db_init(struct idmap_domain *dom) { NTSTATUS ret; struct idmap_ldap_context *ctx = NULL; char *config_option = NULL; const char *range = NULL; const char *tmp = NULL; /* Only do init if we are online */ if (idmap_is_offline()) { return NT_STATUS_FILE_IS_OFFLINE; } ctx = TALLOC_ZERO_P(dom, struct idmap_ldap_context); if ( ! ctx) { DEBUG(0, ("Out of memory!\n")); return NT_STATUS_NO_MEMORY; } config_option = talloc_asprintf(ctx, "idmap config %s", dom->name); if ( ! config_option) { DEBUG(0, ("Out of memory!\n")); ret = NT_STATUS_NO_MEMORY; goto done; } /* load ranges */ range = lp_parm_const_string(-1, config_option, "range", NULL); if (range && range[0]) { if ((sscanf(range, "%u - %u", &ctx->filter_low_id, &ctx->filter_high_id) != 2) || (ctx->filter_low_id > ctx->filter_high_id)) { DEBUG(1, ("ERROR: invalid filter range [%s]", range)); ctx->filter_low_id = 0; ctx->filter_high_id = 0; } } if (dom->params && *(dom->params)) { /* assume location is the only parameter */ ctx->url = talloc_strdup(ctx, dom->params); } else { tmp = lp_parm_const_string(-1, config_option, "ldap_url", NULL); if ( ! tmp) { DEBUG(1, ("ERROR: missing idmap ldap url\n")); ret = NT_STATUS_UNSUCCESSFUL; goto done; } ctx->url = talloc_strdup(ctx, tmp); } CHECK_ALLOC_DONE(ctx->url); tmp = lp_parm_const_string(-1, config_option, "ldap_base_dn", NULL); if ( ! tmp || ! *tmp) { tmp = lp_ldap_idmap_suffix(); if ( ! tmp) { DEBUG(1, ("ERROR: missing idmap ldap suffix\n")); ret = NT_STATUS_UNSUCCESSFUL; goto done; } } ctx->suffix = talloc_strdup(ctx, tmp); CHECK_ALLOC_DONE(ctx->suffix); ret = smbldap_init(ctx, winbind_event_context(), ctx->url, &ctx->smbldap_state); if (!NT_STATUS_IS_OK(ret)) { DEBUG(1, ("ERROR: smbldap_init (%s) failed!\n", ctx->url)); goto done; } ret = get_credentials( ctx, ctx->smbldap_state, config_option, dom, &ctx->user_dn ); if ( !NT_STATUS_IS_OK(ret) ) { DEBUG(1,("idmap_ldap_db_init: Failed to get connection " "credentials (%s)\n", nt_errstr(ret))); goto done; } /* set the destructor on the context, so that resource are properly freed if the contexts is released */ talloc_set_destructor(ctx, idmap_ldap_close_destructor); dom->private_data = ctx; dom->initialized = True; talloc_free(config_option); return NT_STATUS_OK; /*failed */ done: talloc_free(ctx); return ret; }
static NTSTATUS idmap_ldap_alloc_init(const char *params) { NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; const char *range; const char *tmp; uid_t low_uid = 0; uid_t high_uid = 0; gid_t low_gid = 0; gid_t high_gid = 0; /* Only do init if we are online */ if (idmap_is_offline()) { return NT_STATUS_FILE_IS_OFFLINE; } idmap_alloc_ldap = TALLOC_ZERO_P(NULL, struct idmap_ldap_alloc_context); CHECK_ALLOC_DONE( idmap_alloc_ldap ); /* load ranges */ idmap_alloc_ldap->low_uid = 0; idmap_alloc_ldap->high_uid = 0; idmap_alloc_ldap->low_gid = 0; idmap_alloc_ldap->high_gid = 0; range = lp_parm_const_string(-1, "idmap alloc config", "range", NULL); if (range && range[0]) { unsigned low_id, high_id; if (sscanf(range, "%u - %u", &low_id, &high_id) == 2) { if (low_id < high_id) { idmap_alloc_ldap->low_gid = low_id; idmap_alloc_ldap->low_uid = low_id; idmap_alloc_ldap->high_gid = high_id; idmap_alloc_ldap->high_uid = high_id; } else { DEBUG(1, ("ERROR: invalid idmap alloc range " "[%s]", range)); } } else { DEBUG(1, ("ERROR: invalid syntax for idmap alloc " "config:range [%s]", range)); } } if (lp_idmap_uid(&low_uid, &high_uid)) { idmap_alloc_ldap->low_uid = low_uid; idmap_alloc_ldap->high_uid = high_uid; } if (lp_idmap_gid(&low_gid, &high_gid)) { idmap_alloc_ldap->low_gid = low_gid; idmap_alloc_ldap->high_gid= high_gid; } if (idmap_alloc_ldap->high_uid <= idmap_alloc_ldap->low_uid) { DEBUG(1, ("idmap uid range missing or invalid\n")); DEBUGADD(1, ("idmap will be unable to map foreign SIDs\n")); ret = NT_STATUS_UNSUCCESSFUL; goto done; } if (idmap_alloc_ldap->high_gid <= idmap_alloc_ldap->low_gid) { DEBUG(1, ("idmap gid range missing or invalid\n")); DEBUGADD(1, ("idmap will be unable to map foreign SIDs\n")); ret = NT_STATUS_UNSUCCESSFUL; goto done; } if (params && *params) { /* assume location is the only parameter */ idmap_alloc_ldap->url = talloc_strdup(idmap_alloc_ldap, params); } else { tmp = lp_parm_const_string(-1, "idmap alloc config", "ldap_url", NULL); if ( ! tmp) { DEBUG(1, ("ERROR: missing idmap ldap url\n")); ret = NT_STATUS_UNSUCCESSFUL; goto done; } idmap_alloc_ldap->url = talloc_strdup(idmap_alloc_ldap, tmp); } CHECK_ALLOC_DONE( idmap_alloc_ldap->url ); tmp = lp_parm_const_string(-1, "idmap alloc config", "ldap_base_dn", NULL); if ( ! tmp || ! *tmp) { tmp = lp_ldap_idmap_suffix(); if ( ! tmp) { DEBUG(1, ("ERROR: missing idmap ldap suffix\n")); ret = NT_STATUS_UNSUCCESSFUL; goto done; } } idmap_alloc_ldap->suffix = talloc_strdup(idmap_alloc_ldap, tmp); CHECK_ALLOC_DONE( idmap_alloc_ldap->suffix ); ret = smbldap_init(idmap_alloc_ldap, winbind_event_context(), idmap_alloc_ldap->url, &idmap_alloc_ldap->smbldap_state); if (!NT_STATUS_IS_OK(ret)) { DEBUG(1, ("ERROR: smbldap_init (%s) failed!\n", idmap_alloc_ldap->url)); goto done; } ret = get_credentials( idmap_alloc_ldap, idmap_alloc_ldap->smbldap_state, "idmap alloc config", NULL, &idmap_alloc_ldap->user_dn ); if ( !NT_STATUS_IS_OK(ret) ) { DEBUG(1,("idmap_ldap_alloc_init: Failed to get connection " "credentials (%s)\n", nt_errstr(ret))); goto done; } /* see if the idmap suffix and sub entries exists */ ret = verify_idpool(); done: if ( !NT_STATUS_IS_OK( ret ) ) TALLOC_FREE( idmap_alloc_ldap ); return ret; }
pj_bool_t authenticate_rx_request(pjsip_rx_data* rdata) { TRC_DEBUG("Authentication module invoked"); pj_status_t status; bool is_register = (rdata->msg_info.msg->line.req.method.id == PJSIP_REGISTER_METHOD); SNMP::SuccessFailCountTable* auth_stats_table = NULL; std::string resync; SAS::TrailId trail = get_trail(rdata); if (!needs_authentication(rdata, trail)) { TRC_DEBUG("Request does not need authentication"); return PJ_FALSE; } TRC_DEBUG("Request needs authentication"); rapidjson::Document* av = NULL; const int unauth_sc = is_register ? PJSIP_SC_UNAUTHORIZED : PJSIP_SC_PROXY_AUTHENTICATION_REQUIRED; int sc = unauth_sc; status = PJSIP_EAUTHNOAUTH; pjsip_digest_credential* credentials = get_credentials(rdata); if ((credentials != NULL) && (credentials->response.slen != 0)) { std::string impi = PJUtils::pj_str_to_string(&credentials->username); std::string nonce = PJUtils::pj_str_to_string(&credentials->nonce); uint64_t cas = 0; av = av_store->get_av(impi, nonce, cas, trail); if (!is_register) { // Challenged non-register requests must be SIP digest, so only one table // needed for this case. auth_stats_table = auth_stats_tables->non_register_auth_tbl; } else { if (!pj_strcmp2(&credentials->algorithm, "MD5")) { auth_stats_table = auth_stats_tables->sip_digest_auth_tbl; } else if (!pj_strcmp2(&credentials->algorithm, "AKAv1-MD5")) { auth_stats_table = auth_stats_tables->ims_aka_auth_tbl; } else { // Authorization header did not specify an algorithm, so check the av for // this information instead. if ((av != NULL) && (av->HasMember("aka"))) { auth_stats_table = auth_stats_tables->ims_aka_auth_tbl; } else { // Use the digest table if the AV specified digest, or as a fallback if there was no AV auth_stats_table = auth_stats_tables->sip_digest_auth_tbl; } } } if (auth_stats_table != NULL) { auth_stats_table->increment_attempts(); } // Request contains a response to a previous challenge, so pass it to // the authentication module to verify. TRC_DEBUG("Verify authentication information in request"); status = pjsip_auth_srv_verify2((is_register ? &auth_srv : &auth_srv_proxy), rdata, &sc, (void*)av); if (status == PJ_SUCCESS) { // The authentication information in the request was verified. TRC_DEBUG("Request authenticated successfully"); SAS::Event event(trail, SASEvent::AUTHENTICATION_SUCCESS, 0); SAS::report_event(event); if (auth_stats_table != NULL) { auth_stats_table->increment_successes(); } // Write a tombstone flag back to the AV store, handling contention. // We don't actually expect anything else to be writing to this row in // the AV store, but there is a window condition where we failed to read // from the primary, successfully read from the backup (with a different // CAS value) and then try to write back to the primary, which fails due // to "contention". Store::Status store_status; do { // Set the tomestone flag in the JSON authentication vector. rapidjson::Value tombstone_value; tombstone_value.SetBool(true); av->AddMember("tombstone", tombstone_value, (*av).GetAllocator()); // Store it. If this fails due to contention, read the updated JSON. store_status = av_store->set_av(impi, nonce, av, cas, trail); if (store_status == Store::DATA_CONTENTION) { // LCOV_EXCL_START - No support for contention in UT TRC_DEBUG("Data contention writing tombstone - retry"); delete av; av = av_store->get_av(impi, nonce, cas, trail); if (av == NULL) { store_status = Store::ERROR; } // LCOV_EXCL_STOP } } while (store_status == Store::DATA_CONTENTION); if (store_status != Store::OK) { // LCOV_EXCL_START TRC_ERROR("Tried to tombstone AV for %s/%s after processing an authentication, but failed", impi.c_str(), nonce.c_str()); // LCOV_EXCL_STOP } // If doing AKA authentication, check for an AUTS parameter. We only // check this if the request authenticated as actioning it otherwise // is a potential denial of service attack. if (!pj_strcmp(&credentials->algorithm, &STR_AKAV1_MD5)) { TRC_DEBUG("AKA authentication so check for client resync request"); pjsip_param* p = pjsip_param_find(&credentials->other_param, &STR_AUTS); if (p != NULL) { // Found AUTS parameter, so UE is requesting a resync. We need to // redo the authentication, passing an auts parameter to the HSS // comprising the first 16 octets of the nonce (RAND) and the 14 // octets of the auts parameter. (See TS 33.203 and table 6.3.3 of // TS 29.228 for details.) TRC_DEBUG("AKA SQN resync request from UE"); std::string auts = PJUtils::pj_str_to_string(&p->value); std::string nonce = PJUtils::pj_str_to_string(&credentials->nonce); // Convert the auts and nonce to binary for manipulation nonce = base64_decode(nonce); auts = base64_decode(auts); if ((auts.length() != 14) || (nonce.length() != 32)) { // AUTS and/or nonce are malformed, so reject the request. TRC_WARNING("Invalid auts/nonce on resync request from private identity %.*s", credentials->username.slen, credentials->username.ptr); status = PJSIP_EAUTHINAKACRED; sc = PJSIP_SC_FORBIDDEN; } else { // auts and nonce are as expected, so create the resync string // that needs to be passed to the HSS, and act as if no // authentication information was received. The resync string // should be RAND || AUTS. resync = base64_encode(nonce.substr(0, 16) + auts); status = PJSIP_EAUTHNOAUTH; sc = unauth_sc; } } } if (status == PJ_SUCCESS) { // Request authentication completed, so let the message through to other // modules. Remove any Proxy-Authorization headers first so they are not // passed to downstream devices. We can't do this for Authorization // headers, as these may need to be included in 3rd party REGISTER // messages. while (pjsip_msg_find_remove_hdr(rdata->msg_info.msg, PJSIP_H_PROXY_AUTHORIZATION, NULL) != NULL); delete av; return PJ_FALSE; } } } // The message either has insufficient authentication information, or // has failed authentication. In either case, the message will be // absorbed and responded to by the authentication module, so we need to // add SAS markers so the trail will become searchable. SAS::Marker start_marker(trail, MARKER_ID_START, 1u); SAS::report_marker(start_marker); // Add a SAS end marker SAS::Marker end_marker(trail, MARKER_ID_END, 1u); SAS::report_marker(end_marker); // Create an ACR for the message and pass the request to it. Role is always // considered originating for a REGISTER request. ACR* acr = acr_factory->get_acr(trail, CALLING_PARTY, NODE_ROLE_ORIGINATING); acr->rx_request(rdata->msg_info.msg, rdata->pkt_info.timestamp); pjsip_tx_data* tdata; if ((status == PJSIP_EAUTHNOAUTH) || (status == PJSIP_EAUTHACCNOTFOUND)) { // No authorization information in request, or no authentication vector // found in the store (so request is likely stale), so must issue // challenge. TRC_DEBUG("No authentication information in request or stale nonce, so reject with challenge"); pj_bool_t stale = (status == PJSIP_EAUTHACCNOTFOUND); sc = unauth_sc; if (stale && auth_stats_table != NULL) { auth_stats_table->increment_failures(); } status = PJUtils::create_response(stack_data.endpt, rdata, sc, NULL, &tdata); if (status != PJ_SUCCESS) { // Failed to create a response. This really shouldn't happen, but there // is nothing else we can do. // LCOV_EXCL_START delete acr; return PJ_TRUE; // LCOV_EXCL_STOP } create_challenge(credentials, stale, resync, rdata, tdata); } else { // Authentication failed. std::string error_msg = PJUtils::pj_status_to_string(status); TRC_ERROR("Authentication failed, %s", error_msg.c_str()); if (auth_stats_table != NULL) { auth_stats_table->increment_failures(); } SAS::Event event(trail, SASEvent::AUTHENTICATION_FAILED, 0); event.add_var_param(error_msg); SAS::report_event(event); if (sc != unauth_sc) { // Notify Homestead and the HSS that this authentication attempt // has definitively failed. std::string impi; std::string impu; PJUtils::get_impi_and_impu(rdata, impi, impu); hss->update_registration_state(impu, impi, HSSConnection::AUTH_FAIL, trail); } if (analytics != NULL) { analytics->auth_failure(PJUtils::pj_str_to_string(&credentials->username), PJUtils::public_id_from_uri((pjsip_uri*)pjsip_uri_get_uri(PJSIP_MSG_TO_HDR(rdata->msg_info.msg)->uri))); } status = PJUtils::create_response(stack_data.endpt, rdata, sc, NULL, &tdata); if (status != PJ_SUCCESS) { // Failed to create a response. This really shouldn't happen, but there // is nothing else we can do. // LCOV_EXCL_START delete acr; return PJ_TRUE; // LCOV_EXCL_STOP } } acr->tx_response(tdata->msg); // Issue the challenge response transaction-statefully. This is so that: // * if we challenge an INVITE, the UE can ACK the 407 // * if a challenged request gets retransmitted, we don't repeat the work pjsip_transaction* tsx = NULL; status = pjsip_tsx_create_uas2(NULL, rdata, NULL, &tsx); set_trail(tsx, trail); if (status != PJ_SUCCESS) { // LCOV_EXCL_START - defensive code not hit in UT TRC_WARNING("Couldn't create PJSIP transaction for authentication response: %d" " (sending statelessly instead)", status); // Send the response statelessly in this case - it's better than nothing pjsip_endpt_send_response2(stack_data.endpt, rdata, tdata, NULL, NULL); // LCOV_EXCL_STOP } else { // Let the tsx know about the original message pjsip_tsx_recv_msg(tsx, rdata); // Send our response in this transaction pjsip_tsx_send_msg(tsx, tdata); } // Send the ACR. acr->send(); delete acr; delete av; return PJ_TRUE; }
pj_status_t user_lookup(pj_pool_t *pool, const pjsip_auth_lookup_cred_param *param, pjsip_cred_info *cred_info, void* av_param) { const pj_str_t* acc_name = ¶m->acc_name; const pj_str_t* realm = ¶m->realm; const pjsip_rx_data* rdata = param->rdata; SAS::TrailId trail = get_trail(rdata); pj_status_t status = PJSIP_EAUTHACCNOTFOUND; // Get the impi and the nonce. There must be an authorization header otherwise // PJSIP wouldn't have called this method. std::string impi = PJUtils::pj_str_to_string(acc_name); pjsip_digest_credential* credentials = get_credentials(rdata); std::string nonce = PJUtils::pj_str_to_string(&credentials->nonce); // Get the Authentication Vector from the store. rapidjson::Document* av = (rapidjson::Document*)av_param; if (av == NULL) { TRC_WARNING("Received an authentication request for %s with nonce %s, but no matching AV found", impi.c_str(), nonce.c_str()); } if ((av != NULL) && (!verify_auth_vector(av, impi, trail))) { // Authentication vector is badly formed. av = NULL; // LCOV_EXCL_LINE } if (av != NULL) { pj_cstr(&cred_info->scheme, "digest"); pj_strdup(pool, &cred_info->username, acc_name); if (av->HasMember("aka")) { pjsip_param* auts_param = pjsip_param_find(&credentials->other_param, &STR_AUTS); // AKA authentication. The response in the AV must be used as a // plain-text password for the MD5 Digest computation. Convert the text // into binary as this is what PJSIP is expecting. If we find the 'auts' // parameter, then leave the response as the empty string in accordance // with RFC 3310. std::string response = ""; if (((*av)["aka"].HasMember("response")) && ((*av)["aka"]["response"].IsString()) && auts_param == NULL) { response = (*av)["aka"]["response"].GetString(); } std::string xres; for (size_t ii = 0; ii < response.length(); ii += 2) { xres.push_back((char)(pj_hex_digit_to_val(response[ii]) * 16 + pj_hex_digit_to_val(response[ii+1]))); } cred_info->data_type = PJSIP_CRED_DATA_PLAIN_PASSWD; pj_strdup2(pool, &cred_info->data, xres.c_str()); TRC_DEBUG("Found AKA XRES = %.*s", cred_info->data.slen, cred_info->data.ptr); // Use default realm as it isn't specified in the AV. pj_strdup(pool, &cred_info->realm, realm); status = PJ_SUCCESS; } else if (av->HasMember("digest")) { std::string digest_realm = ""; if (((*av)["digest"].HasMember("realm")) && ((*av)["digest"]["realm"].IsString())) { digest_realm = (*av)["digest"]["realm"].GetString(); } if (pj_strcmp2(realm, digest_realm.c_str()) == 0) { // Digest authentication, so ha1 field is hashed password. cred_info->data_type = PJSIP_CRED_DATA_DIGEST; std::string digest_ha1 = ""; if (((*av)["digest"].HasMember("ha1")) && ((*av)["digest"]["ha1"].IsString())) { digest_ha1 = (*av)["digest"]["ha1"].GetString(); } pj_strdup2(pool, &cred_info->data, digest_ha1.c_str()); cred_info->realm = *realm; TRC_DEBUG("Found Digest HA1 = %.*s", cred_info->data.slen, cred_info->data.ptr); status = PJ_SUCCESS; } else { // These credentials are for a different realm, so no credentials were // actually provided for us to check. status = PJSIP_EAUTHNOAUTH; } } correlate_branch_from_av(av, trail); } return status; }