aboutsummaryrefslogtreecommitdiff
path: root/lib/libostp/auth.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libostp/auth.c')
-rw-r--r--lib/libostp/auth.c95
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);