Пример #1
0
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;
}
Пример #2
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;
}
Пример #3
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;
}
Пример #4
0
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));
}
Пример #5
0
/**@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));
}
Пример #6
0
/**
 * 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);
    }
}
Пример #7
0
/* 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;
}
Пример #8
0
/**
 * 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;
        } 
    }
}
Пример #9
0
/**
 * 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);
}