int sharedaemon_bcast_send_peer(shpeer_t *peer) { struct sockaddr_in addr; socklen_t addr_len; struct timeval to; fd_set write_set; char dgram[512]; ssize_t w_len; int fd; int err; fd = bcast_send_init(); if (fd < 0) { fprintf(stderr, "DEBUG: sharedaemon_bcast_send: bcast_init error %d\n", err); return (err); } FD_ZERO(&write_set); FD_SET(fd, &write_set); /* nonblocking write */ memset(&to, 0, sizeof(to)); err = select(fd+1, NULL, &write_set, NULL, &to); if (err < 0) { close(fd); return (-errno); } if (err == 0) { close(fd); return (0); /* not able to send */ } memset(dgram, 0, sizeof(dgram)); memcpy(dgram, peer, sizeof(shpeer_t)); addr_len = sizeof(addr); memset(&addr, 0, addr_len); addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_BROADCAST); addr.sin_port = htons(SHARED_BROADCAST_PORT); w_len = sendto(fd, dgram, sizeof(shpeer_t), 0, &addr, sizeof(addr)); if (w_len < 0) { fprintf(stderr, "DEBUG: sharedaemon_bcast_send: sendto error: %s\n", strerror(errno)); close(fd); return (-errno); } fprintf(stderr, "DEBUG: sharedaemon_bcast_send: peer \"%s\" <%d bytes>\n", shpeer_print(peer), w_len); fprintf(stderr, "DEBUG: peer pubkey: %s\n", shkey_print(shpeer_kpub(peer))); fprintf(stderr, "DEBUG: peer priv key: %s\n", shkey_print(shpeer_kpriv(peer))); /* close socket; only used once. */ close(fd); return (0); }
void shcert_print(shcert_t *cert, shbuf_t *pr_buff) { char tbuf1[256]; char tbuf2[256]; char buf[4096]; if (!cert || !pr_buff) return; shbuf_catstr(pr_buff, "Certificate:\n"); shbuf_catstr(pr_buff, " Data:\n"); sprintf(buf, " Version: %d\n", cert->cert_ver); shbuf_catstr(pr_buff, buf); shbuf_catstr(pr_buff, " Serial Number: "); shcert_hex_print(pr_buff, shcert_sub_ser(cert), sizeof(shcert_sub_ser(cert)), ""); sprintf(buf, " Signature Algorithm: %s\n", shsig_alg_str(shcert_iss_alg(cert) | shcert_sub_alg(cert))); shbuf_catstr(pr_buff, buf); sprintf(buf, " Issuer: %s\n", cert->cert_iss.ent_name); shbuf_catstr(pr_buff, buf); strcpy(tbuf1, shctime(shcert_sub_stamp(cert))+4); strcpy(tbuf2, shctime(shcert_sub_expire(cert))+4); sprintf(buf, " Validity: %-20.20s - %-20.20s\n", tbuf1, tbuf2); shbuf_catstr(pr_buff, buf); sprintf(buf, " Subject: %s\n", cert->cert_sub.ent_name); shbuf_catstr(pr_buff, buf); sprintf(buf, " Public Key Algorithm: (%d bit) %s\n", shcert_sub_len(cert) * 8, shsig_alg_str(shcert_sub_alg(cert))); shbuf_catstr(pr_buff, buf); sprintf(buf, " Checksum: %llu\n", shkey_crc(shcert_sub_sig(cert))); sprintf(buf, " 192-Bit: %s\n", shkey_hex(shcert_sub_sig(cert))); shbuf_catstr(pr_buff, buf); if (shcert_sub_alg(cert) & SHKEY_ALG_RSA) { shbuf_catstr(pr_buff, " Modulus:\n"); shcert_hex_print_reverse(pr_buff, cert->cert_sub.ent_sig.key.rsa.mod, cert->cert_sub.ent_sig.key.rsa.mod_len, " "); } shbuf_catstr(pr_buff, " X509v3 extensions:\n"); sprintf(buf, " Basic Constraints: CA=%s\n", (cert->cert_flag & SHCERT_CERT_CHAIN) ? "false" : "true"); shbuf_catstr(pr_buff, buf); if (!shpeer_localhost(&cert->cert_sub.ent_peer)) { sprintf(buf, " Alternate Subject: %s\n", shpeer_print(&cert->cert_sub.ent_peer)); shbuf_catstr(pr_buff, buf); } sprintf(buf, " Extended Usage: %s\n", shcert_flag_str(cert->cert_flag)); shbuf_catstr(pr_buff, buf); sprintf(buf, " Private Signature: %s (%d bytes)\n", shsig_alg_str(shcert_iss_alg(cert)), shcert_iss_len(cert)); shbuf_catstr(pr_buff, buf); if (shcert_iss_alg(cert) & SHKEY_ALG_MD5) { shcert_hex_print(pr_buff, cert->cert_iss.ent_sig.key.md.md, cert->cert_iss.ent_sig.key.md.md_len, " "); } else if (shcert_iss_alg(cert) & SHKEY_ALG_SHA1) { shcert_hex_print(pr_buff, cert->cert_iss.ent_sig.key.sha.sha, cert->cert_iss.ent_sig.key.sha.sha_len, " "); } else if (shcert_iss_alg(cert) & SHKEY_ALG_SHA256) { shcert_hex_print(pr_buff, cert->cert_iss.ent_sig.key.sha.sha, cert->cert_iss.ent_sig.key.sha.sha_len, " "); } else { sprintf(buf, " Checksum: %llu\n", shkey_crc(shcert_iss_sig(cert))); shbuf_catstr(pr_buff, buf); sprintf(buf, " 192-Bit: %s\n", shkey_hex(shcert_iss_sig(cert))); shbuf_catstr(pr_buff, buf); } }
int sharedaemon_bcast_recv(void) { struct sockaddr_in addr; socklen_t addr_len; struct timeval to; fd_set read_set; shpeer_t *peer; char dgram[512]; ssize_t r_len; int err; err = bcast_recv_init(); if (err) { return (err); } FD_ZERO(&read_set); FD_SET(_bcast_recv_fd, &read_set); /* nonblocking read */ memset(&to, 0, sizeof(to)); err = select(_bcast_recv_fd+1, &read_set, NULL, NULL, &to); if (err < 0) { return (-errno); } if (err == 0) { //fprintf(stderr, "\rWaiting for select(_bcast_recv_fd).."); //fflush(stderr); return (0); /* nothing to read */ } addr_len = sizeof(addr); memset(&addr, 0, addr_len); r_len = recvfrom(_bcast_recv_fd, dgram, sizeof dgram, 0, &addr, &addr_len); if (r_len < 0) { fprintf(stderr, "DEBUG: %d = recvfrom()\n", r_len); return (-errno); } /* and who are you? */ if (r_len < sizeof(shpeer_t)) { fprintf(stderr, "DEBUG: <%d bytes> pending..\n", r_len); return (SHERR_INVAL); } #if 0 now = shtime(); tx = (tx_t *)dgram; if (shtime_after(tx->tx_stamp, now) || shtime_before(tx->tx_stamp, shtime_adj(now, -BROADCAST_TIMEOUT))) { /* broadcast message must indicate sane time-frame. */ return (SHERR_TIME); } switch (tx->tx_op) { case TX_PEER: peer_tx = (tx_peer_t *)dgram; if (0 != shkey_cmp(&tx->tx_peer, shpeer_kpriv(&peer_tx->peer))) return (SHERR_INVAL); /* only accept self-referencing broadcast */ } #endif /* share-daemon broadcasting it's peer address. */ peer = (shpeer_t *)dgram; if (!shkey_cmp(shpeer_kpub(sharedaemon_peer()), shpeer_kpub(peer))) { /* this is not a shared peer */ return (0); /* all done */ } if (!shkey_cmp(shpeer_kpub(sharedaemon_peer()), shpeer_kpub(peer))) { fprintf(stderr, "DEBUG: invalid key\n"); /* this is a peer referencing ourselves. */ //err = sharedaemon_netclient_alias(&addr); } switch (peer->type) { case SHNET_PEER_LOCAL: case SHNET_PEER_IPV4: /* memset(&addr, '\000', sizeof(struct sockaddr_in)); memcpy(&addr, &peer_tx->peer.addr, sizeof(peer_tx->peer.addr)); */ fprintf(stderr, "DEBUG: received UDP broadcast with peer \"%s\"\n", shpeer_print(peer)); fprintf(stderr, "DEBUG: received UDP broadcast for \"%s\" port %d\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port)); if (!peer->addr.sin_port) break; /* otay */ addr.sin_family = AF_INET; err = sharedaemon_netclient_conn(peer, &addr); if (err) return (err); break; } fprintf(stderr, "DEBUG: processed bcast recv\n"); return (0); }