diff options
Diffstat (limited to 'lib/libostp/auth.c')
-rw-r--r-- | lib/libostp/auth.c | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/lib/libostp/auth.c b/lib/libostp/auth.c index 5fa59e9..ddc17b8 100644 --- a/lib/libostp/auth.c +++ b/lib/libostp/auth.c @@ -30,8 +30,10 @@ #include <sys/wait.h> #include <sys/socket.h> #include <ostp/net/auth.h> +#include <ostp/net/stpsession.h> #include <ostp/crypto/ecdh.h> #include <ostp/otconfig.h> +#include <ostp/defs.h> #include <arpa/inet.h> #include <stdio.h> #include <unistd.h> @@ -133,6 +135,78 @@ send_motd(struct ostp_client *c, const unsigned char *session_key) } } +static inline void +populate_peer(struct ostp_client *c, struct peer *pp) +{ + memset(pp, 0, sizeof(*pp)); + pp->port = htons(OSTP_PORT); + pp->pad[0] = 0xFF; + memcpy(pp->host, c->host, IP_LEN_MAX); +} + +static int +send_peerlist(struct ostp_listener *lp, struct ostp_client *c, struct ostp_session *s) +{ + struct ostp_client *c_cur, *c_tmp; + struct peer peer_cur; + struct peer_block pb_cur; + struct ostp_session *sp; + size_t peer_count; + int i, j, error; + int seq; + + memset(&pb_cur, 0, sizeof(pb_cur)); + peer_count = lp->client_count; + seq = (peer_count <= 16) ? 1 : (peer_count / PB_N_PEERS); + pb_cur.seq = seq; + printf("peer_count=%d, seq=%d\n", peer_count, pb_cur.seq); + + /* + * Grab peers and prepare blocks until seq == 0 + * + * + * lp->clients + * +-------------------+ + * i=| | | | | | | | | | | + * +-------------------+ + * 0,1,2,3,4,5,6,7,8,9 <--+ + * | + * pb_cur.peers | + * +---------------+ | lp->clients can be bigger + * j=| | | | | | | | | | + * +---------------+ + + * 0,1,2,3,4,5,6,7 <---+-/ + * + * + * lp->clients is one big contigious array + * of connected clients and is used internally + * by the server to manage connected users. + * + * During a session request, the client may request + * peer-to-peer mode by setting the 'P' bit. If accepted, + * we'll need to send one or more peer blocks back, containing + * a list of `PB_N_PEERS' peers max per block. + * + */ + for (i = 0; i < PB_N_BLOCKS && seq > 0; ++i) { + for (j = 1; j < PB_N_PEERS && j < peer_count; ++j) { + populate_peer(&lp->clients[j], &peer_cur); + pb_cur.peers[j] = peer_cur; + } + + --seq; + pb_cur.seq = seq; + sp = &c->session; + session_send(&pb_cur, sizeof(pb_cur), sp); + + if (j >= lp->client_count) { + break; + } + } + + return 0; +} + int handle_srq(struct ostp_client *c, struct ostp_listener *lp, struct session_request *srq) { @@ -140,12 +214,20 @@ handle_srq(struct ostp_client *c, struct ostp_listener *lp, struct session_reque struct ostp_session *session; int error; + /* Do we require the SRQ 'U' bit? */ if (REQUIRE_USER_AUTH && !ISSET(srq->options, SESSION_REQ_USER)) { printf("User authentication enforced but client 'U' bit not set\n"); printf("Closing connection...\n"); return -1; } + /* Don't use P2P if not enabled */ + if (!ENABLE_P2P && !ISSET(srq->options, SESSION_REQ_P2P)) { + printf("P2P not enabled but client 'P' bit set\n"); + printf("Closing connection...\n"); + return -1; + } + /* Generate a new keypair if we have no link */ if (!g_have_link) { if (gen_x25519_keypair(&keypair) < 0) { @@ -183,6 +265,19 @@ handle_srq(struct ostp_client *c, struct ostp_listener *lp, struct session_reque return -1; } + /* Handle P2P requests */ + if (ISSET(srq->options, SESSION_REQ_P2P)) { + /* + * Not an error but we want to send this down + * the callstack so everything is cleaned up + * and terminated properly. + * + * TODO: Figure something else out here maybe... + */ + send_peerlist(lp, c, session); + return -1; + } + /* Handle any requested session parameters */ if ((error = negotiate_spw(c, session->session_key)) < 0) { free_session_key(session->session_key); |