int shpam_pshadow_set(shfs_ino_t *file, shseed_t *seed, shkey_t *sess_key) { shadow_t save; int err; err = shpam_shadow_load(file, seed->seed_uid, &save); if (err) return (err); /* validate session key */ if (shtime_after(shtime(), save.sh_expire)) return (SHERR_KEYEXPIRED); if (!shkey_cmp(&save.sh_sess, sess_key)) return (SHERR_KEYREJECTED); err = shpam_shadow_session_expire(file, seed->seed_uid, sess_key); if (err) return (err); err = shpam_pshadow_store(file, seed); if (err) return (err); return (0); }
int shpam_shadow_remove(shfs_ino_t *file, uint64_t uid, shkey_t *sess_key) { shadow_t *ent; shadow_t save; shkey_t *key; int err; if (!sess_key) return (SHERR_NOKEY); err = shpam_shadow_load(file, uid, &save); if (err) { return (err); } if (shtime_after(shtime(), save.sh_expire)) return (SHERR_KEYEXPIRED); if (!shkey_cmp(&save.sh_sess, sess_key)) return (SHERR_KEYREJECTED); key = shkey_bin((char *)&uid, sizeof(uid)); err = shfs_cred_remove(file, key); shkey_free(&key); if (err) { return (err); } return (0); }
int txop_contract_confirm(shpeer_t *peer, tx_contract_t *contract) { shtime_t now; shkey_t *key; int sig_ok; if (0 != strcmp(contract->con_cur, COIN_USDE) && 0 != strcmp(contract->con_cur, COIN_GMC) && 0 != strcmp(contract->con_cur, COIN_SYS)) return (SHERR_INVAL); now = shtime(); if (shtime_before(shtime(), contract->con_birth) || shtime_before(shtime(), contract->con_stamp) || shtime_after(contract->con_birth, contract->con_stamp)) return (SHERR_TIME); key = shkey_hexgen(contract->con_key + 8); if (!key) return (SHERR_NOKEY); sig_ok = shkey_cmp(key, &contract->con_sig); shkey_free(&key); if (!sig_ok) return (SHERR_KEYREJECTED); return (0); }
int shpam_shadow_session(shfs_ino_t *file, shseed_t *seed, shkey_t **sess_p, shtime_t *expire_p) { shadow_t *ent; shadow_t save; shkey_t *sess_key; shkey_t *ret_key; shkey_t *seed_key; shtime_t stamp; shtime_t now; uint64_t crc; int err; if (!file->tree) return (SHERR_INVAL); err = shpam_shadow_load(file, seed->seed_uid, &save); if (err) { return (err); } now = shtime(); if (shtime_after(now, save.sh_expire)) { /* generate new session key with default expiration */ stamp = shtime_adj(now, MAX_SHARE_SESSION_TIME); sess_key = _shpam_shadow_session_gen(seed, &save.sh_id, stamp); if (!sess_key) return (SHERR_KEYREVOKED); save.sh_expire = stamp; memcpy(&save.sh_sess, sess_key, sizeof(save.sh_sess)); err = shpam_shadow_store(file, &save); shkey_free(&sess_key); if (err) { return (err); } } if (expire_p) *expire_p = save.sh_expire; if (sess_p) { ret_key = (shkey_t *)calloc(1, sizeof(shkey_t)); memcpy(ret_key, &save.sh_sess, sizeof(shkey_t)); *sess_p = ret_key; } return (0); }
int shpam_shadow_session_expire(shfs_ino_t *file, uint64_t uid, shkey_t *sess_key) { shadow_t *ent; shadow_t save; int err; err = shpam_shadow_load(file, uid, &save); if (err) return (err); if (shtime_after(shtime(), save.sh_expire)) return (SHERR_KEYEXPIRED); if (!shkey_cmp(&save.sh_sess, sess_key)) return (SHERR_KEYREJECTED); save.sh_expire = 0; err = shpam_shadow_store(file, &save); if (err) return (err); return (0); }
int shcert_verify(shcert_t *cert, shcert_t *parent) { shtime_t now; int err; if (!(cert->cert_flag & SHCERT_CERT_CHAIN)) { /* initial (CA) chain entity */ if (parent) return (SHERR_INVAL); return (0); } /* supplemental chain entity */ if (!parent) return (SHERR_INVAL); /* The Issuer of each certificate (except the last one) matches the Subject of the next (parent) certificate in the list. */ if (0 != strcasecmp(cert->cert_iss.ent_name, parent->cert_sub.ent_name)) { return (SHERR_ACCESS); } now = shtime(); if (!shtime_after(now, shcert_sub_stamp(cert))) { return (SHERR_ACCESS); } if (!shtime_before(now, shcert_sub_expire(cert))) { return (SHERR_KEYEXPIRED); } /* The signature of one certificate can be verified using the public key contained in the following certificate. */ err = shcert_sign_verify(cert, parent); if (err) return (err); return (0); }
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); }