struct Peer *get_peer(struct sockaddr *addr, socklen_t len) { struct Peer *result; for (result = peers; result; result = result->next) if (addr_equal(&result->addr, result->addr_len, addr, len)) return result; return 0; }
/** * Checks to see if the multicast address used for the given group list member * is also being used by either another member or the public address list */ int other_mcast_users(struct pr_group_list_t *group) { int i; for (i = 0; i < pub_multi_count; i++) { if (addr_equal(&group->privatemcast, &pub_multi[i])) { return 1; } } for (i = 0; i < MAXLIST; i++) { if ((&group_list[i] != group) && (group_list[i].group_id != 0) && (addr_equal(&group->privatemcast, &group_list[i].privatemcast))) { return 1; } } return 0; }
/* * Find the node belonging to a given socket address (for incoming * connections). */ static struct node * sockaddr_to_node(struct sockaddr *sa, socklen_t sa_len) { struct node *node; for (node = nodes; node; node = node->next) { if (addr_equal(sa, node->addr->sa)) return node; } return NULL; }
int addr_inside(const struct addr * const a, const struct addr * const net, const struct addr * const mask) { struct addr masked; assert(a->family == net->family); assert(a->family == mask->family); masked = *a; addr_mask(&masked, mask); return (addr_equal(&masked, net)); }
/**@brief This function checks if two variables of type ble_gap_evt_auth_status_t are equal. * * @param[in] p_auth_status_1 Variable 1. * @param[in] p_auth_status_2 Variable 2. * * @return TRUE if all fields in the two variables are equal, FALSE otherwise. */ static bool auth_status_equal(ble_gap_evt_auth_status_t * p_auth_status_1, ble_gap_evt_auth_status_t * p_auth_status_2) { return ((p_auth_status_1->auth_status == p_auth_status_2->auth_status) && (p_auth_status_1->error_src == p_auth_status_2->error_src) && sec_levels_equal(&p_auth_status_1->sm1_levels, &p_auth_status_2->sm1_levels) && sec_levels_equal(&p_auth_status_1->sm2_levels, &p_auth_status_2->sm2_levels) && sec_keys_equal(&p_auth_status_1->periph_kex, &p_auth_status_2->periph_kex) && sec_keys_equal(&p_auth_status_1->central_kex, &p_auth_status_2->central_kex) && enc_info_equal(&p_auth_status_1->periph_keys.enc_info, &p_auth_status_2->periph_keys.enc_info) && irk_equal(&p_auth_status_1->central_keys.irk, &p_auth_status_2->central_keys.irk) && addr_equal(&p_auth_status_1->central_keys.id_info, &p_auth_status_2->central_keys.id_info)); }
/** * Handles an ABORT message from a client or server * and forwards if necessary. */ void handle_abort(struct pr_group_list_t *group, const union sockaddr_u *src, const unsigned char *message, unsigned meslen, uint32_t src_id) { const struct abort_h *abort_hdr; int upstream, hostidx, current; abort_hdr = (const struct abort_h *)message; upstream = (addr_equal(&group->up_addr, src)); if (meslen < (abort_hdr->hlen * 4U) || ((abort_hdr->hlen * 4U) < sizeof(struct abort_h))) { glog1(group, "Rejecting ABORT from %s: invalid message size", upstream ? "server" : "client"); } if (upstream) { if ((abort_hdr->host == 0) || abort_hdr->host == uid ) { glog1(group, "Transfer aborted by server: %s", abort_hdr->message); current = ((abort_hdr->flags & FLAG_CURRENT_FILE) != 0); if (proxy_type != RESPONSE_PROXY) { send_downstream_abort(group, 0, abort_hdr->message, current); } if (!current) { group_cleanup(group); } } else { if (proxy_type != RESPONSE_PROXY) { send_downstream_abort(group, abort_hdr->host, abort_hdr->message, 0); } } } else { if ((hostidx = find_client(group, src_id)) != -1) { glog1(group, "Transfer aborted by %s: %s", group->destinfo[hostidx].name, abort_hdr->message); } else { glog1(group, "Transfer aborted by %08X: %s", ntohl(src_id), abort_hdr->message); } send_upstream_abort(group, src_id, abort_hdr->message); } }
/* Receive message and identify buddy */ PurpleBuddy *receive_msg(plain_plugin_state *pstate, IP *addr_ret, char buf[], int *buf_length) { char addrbuf[FULL_ADDSTRLEN+1]; PurpleBuddy *buddy; plain_buddy_state *bstate; GSList *iter; socklen_t addrlen; IP addr; int n; addrlen = sizeof(IP); n = recvfrom(pstate->sockfd, buf, *buf_length, 0, (struct sockaddr *) &addr, &addrlen); if (n < 0 || n > *buf_length) { buf[0] = '\0'; *buf_length = 0; return NULL; } else { buf[n] = '\0'; *buf_length = n; } memcpy(addr_ret, &addr, sizeof(IP)); iter = pstate->all_buddies; while (iter) { buddy = iter->data; bstate = purple_buddy_get_protocol_data(buddy); const char *addr_str = purple_blist_node_get_string(PURPLE_BLIST_NODE(buddy), "addr_str"); //printf("buddy: %s, addr: %s (addr_str: %s)\n", bstate->name, str_addr(&bstate->addr, addrbuf), addr_str); if(addr_equal(&bstate->addr, &addr)) { /* Found buddy by address */ return buddy; } iter = iter->next; } /* No buddy found */ return NULL; }
/** * Process a PROXY_KEY message */ void handle_proxy_key(const union sockaddr_u *src, unsigned char *message, unsigned meslen) { struct proxy_key_h *proxykey; unsigned char *keyblob, *dhblob, *sig; unsigned char fingerprint[HMAC_LEN]; unsigned int fplen, keylen, dhlen, siglen; char addrname[INET6_ADDRSTRLEN]; int rval; proxykey = (struct proxy_key_h *)message; if (meslen < (proxykey->hlen * 4U) || ((proxykey->hlen * 4U) < sizeof(struct proxy_key_h) + ntohs(proxykey->bloblen) + ntohs(proxykey->dhlen) + ntohs(proxykey->siglen))) { log2(0, 0, 0, "Rejecting PROXY_KEY: invalid message size"); return; } if ((rval = getnameinfo((const struct sockaddr *)src, family_len(*src), addrname, sizeof(addrname), NULL, 0, NI_NUMERICHOST)) != 0) { log1(0, 0, 0, "getnameinfo failed: %s", gai_strerror(rval)); } log2(0, 0, 0, "Received PROXY_KEY from %s", addrname); if (!has_proxy) { log2(0, 0, 0, "No reply proxy specified"); return; } if (!addr_equal(&proxy_info.addr, src)) { log2(0, 0, 0, "PROXY_KEY not from specified reply proxy"); return; } keyblob = (unsigned char *)proxykey + sizeof(struct proxy_key_h); keylen = ntohs(proxykey->bloblen); dhblob = keyblob + keylen; dhlen = ntohs(proxykey->dhlen); sig = dhblob + dhlen; siglen = ntohs(proxykey->siglen); if (keyblob[0] == KEYBLOB_RSA) { if (!import_RSA_key(&proxy_pubkey.rsa, keyblob, keylen)) { log0(0, 0, 0, "Failed to import public key from PROXY_KEY"); return; } if (proxy_info.has_fingerprint) { hash(HASH_SHA1, keyblob, keylen, fingerprint, &fplen); if (memcmp(proxy_info.fingerprint, fingerprint, fplen)) { log1(0, 0, 0, "Failed to verify PROXY_KEY fingerprint"); free_RSA_key(proxy_pubkey.rsa); return; } } if (!verify_RSA_sig(proxy_pubkey.rsa, HASH_SHA1, (unsigned char *)&proxykey->nonce, sizeof(proxykey->nonce), sig, siglen)) { log1(0, 0, 0, "Failed to verify PROXY_KEY signature"); free_RSA_key(proxy_pubkey.rsa); return; } } else { if (!import_EC_key(&proxy_pubkey.ec, keyblob, keylen, 0)) { log0(0, 0, 0, "Failed to import public key from PROXY_KEY"); return; } if (proxy_info.has_fingerprint) { hash(HASH_SHA1, keyblob, keylen, fingerprint, &fplen); if (memcmp(proxy_info.fingerprint, fingerprint, fplen)) { log1(0, 0, 0, "Failed to verify PROXY_KEY fingerprint"); free_RSA_key(proxy_pubkey.rsa); return; } } if (!verify_ECDSA_sig(proxy_pubkey.ec, HASH_SHA1, (unsigned char *)&proxykey->nonce, sizeof(proxykey->nonce), sig, siglen)) { log1(0, 0, 0, "Failed to verify PROXY_KEY signature"); free_RSA_key(proxy_pubkey.rsa); return; } } if (dhlen) { if (!import_EC_key(&proxy_dhkey.ec, dhblob, dhlen, 1)) { log0(0, 0, 0, "Failed to import ECDH public key from PROXY_KEY"); return; } } }
/** * Process an HB_REQ message */ void handle_hb_request(const union sockaddr_u *src, unsigned char *packet, unsigned packetlen) { struct hb_req_h *hbreq; unsigned char *keyblob, *sig; union key_t key; unsigned char fingerprint[HMAC_LEN]; unsigned int fplen, bloblen, siglen; char destname[INET6_ADDRSTRLEN], destport[PORTNAME_LEN]; int resp, rval; hbreq = (struct hb_req_h *)(packet + sizeof(struct uftp_h)); if ((rval = getnameinfo((const struct sockaddr *)src, family_len(*src), destname, sizeof(destname), destport, sizeof(destport), NI_NUMERICHOST | NI_NUMERICSERV)) != 0) { log1(0, 0, 0, "getnameinfo failed: %s", gai_strerror(rval)); } if ((packetlen < sizeof(struct uftp_h) + (hbreq->hlen * 4)) || ((hbreq->hlen * 4) < sizeof(struct hb_req_h))) { log1(0,0,0, "Rejecting HB_REQ from %s: invalid message size", destname); return; } log2(0, 0, 0, "Received HB_REQ from %s", destname); if ((proxy_type == SERVER_PROXY) && have_down_fingerprint) { if (addr_equal(&down_addr, src)) { resp = HB_AUTH_OK; } else if (down_nonce != ntohl(hbreq->nonce)) { resp = HB_AUTH_CHALLENGE; } else { keyblob = (unsigned char *)hbreq + sizeof(struct hb_req_h); bloblen = ntohs(hbreq->bloblen); sig = keyblob + bloblen; siglen = ntohs(hbreq->siglen); // First check key fingerprint, then check signature if (keyblob[0] == KEYBLOB_RSA) { if (!import_RSA_key(&key.rsa, keyblob, bloblen)) { log1(0, 0, 0, "Failed to import public key from HB_REQ"); resp = HB_AUTH_FAILED; goto end; } hash(HASH_SHA1, keyblob, bloblen, fingerprint, &fplen); if (memcmp(down_fingerprint, fingerprint, fplen)) { log1(0, 0, 0, "Failed to verify HB_REQ fingerprint"); resp = HB_AUTH_FAILED; goto end; } if (!verify_RSA_sig(key.rsa, HASH_SHA1, (unsigned char *)&hbreq->nonce, sizeof(hbreq->nonce), sig, siglen)) { log1(0, 0, 0, "Failed to verify HB_REQ signature"); resp = HB_AUTH_FAILED; goto end; } } else { if (!import_EC_key(&key.ec, keyblob, bloblen, 0)) { log1(0, 0, 0, "Failed to import public key from HB_REQ"); resp = HB_AUTH_FAILED; goto end; } hash(HASH_SHA1, keyblob, bloblen, fingerprint, &fplen); if (memcmp(down_fingerprint, fingerprint, fplen)) { log1(0, 0, 0, "Failed to verify HB_REQ fingerprint"); resp = HB_AUTH_FAILED; goto end; } if (!verify_ECDSA_sig(key.ec, HASH_SHA1, (unsigned char *)&hbreq->nonce, sizeof(hbreq->nonce), sig, siglen)) { log1(0, 0, 0, "Failed to verify HB_REQ signature"); resp = HB_AUTH_FAILED; goto end; } } down_addr = *src; log2(0, 0, 0, "Using %s:%s as downstream address:port", destname, destport); down_nonce = rand32(); resp = HB_AUTH_OK; } } else { resp = HB_AUTH_OK; } end: send_hb_response(src, resp); }