From 40974e78dd09521712ccda5d9bd1c1eb4821d7eb Mon Sep 17 00:00:00 2001 From: Alexander Couzens Date: Thu, 23 Mar 2023 17:44:19 +0100 Subject: [PATCH] osmo-epdg: implement Tunnel Request/Response Requires gsup message types in libosmocore --- src/libcharon/plugins/osmo_epdg/gsup_client.c | 42 +++++++++++++++++++ src/libcharon/plugins/osmo_epdg/gsup_client.h | 8 ++++ .../plugins/osmo_epdg/osmo_epdg_listener.c | 30 +++++++++++-- .../plugins/osmo_epdg/osmo_epdg_utils.c | 22 ++++++++++ .../plugins/osmo_epdg/osmo_epdg_utils.h | 2 + 5 files changed, 100 insertions(+), 4 deletions(-) diff --git a/src/libcharon/plugins/osmo_epdg/gsup_client.c b/src/libcharon/plugins/osmo_epdg/gsup_client.c index fb3196927..709de42fd 100644 --- a/src/libcharon/plugins/osmo_epdg/gsup_client.c +++ b/src/libcharon/plugins/osmo_epdg/gsup_client.c @@ -194,6 +194,47 @@ static bool enqueue(private_osmo_epdg_gsup_client_t *this, gsup_request_t *req, return ret; } +METHOD(osmo_epdg_gsup_client_t, tunnel_request, osmo_epdg_gsup_response_t*, + private_osmo_epdg_gsup_client_t *this, char *imsi, char *apn) +{ + struct osmo_gsup_message gsup_msg = {0}; + struct msgb *msg; + bool timedout; + + DBG1(DBG_NET, "Tunnel Request Request for %s", imsi); + gsup_msg.message_type = OSMO_GSUP_MSGT_EPDG_TUNNEL_REQUEST; + gsup_msg.current_rat_type = OSMO_RAT_EUTRAN_SGS; + + if (!imsi || strlen(imsi) == 0) + { + /* TODO: inval imsi! */ + return NULL; + } + strncpy(gsup_msg.imsi, imsi, sizeof(gsup_msg.imsi)); + + msg = encode_to_msgb(&gsup_msg); + if (!msg) + { + DBG1(DBG_NET, "Couldn't alloc/encode gsup message."); + return NULL; + } + + /* TODO: add APN! */ + gsup_request_t *req = gsup_request_create(OSMO_GSUP_MSGT_SEND_AUTH_INFO_REQUEST, msg); + osmo_epdg_gsup_response_t *resp = NULL; + timedout = enqueue(this, req, 5000); + if (timedout) + { + gsup_request_destroy(this, req); + return NULL; + } + + resp = req->resp; + req->resp = NULL; + gsup_request_destroy(this, req); + return ret; +} + METHOD(osmo_epdg_gsup_client_t, send_auth_request, osmo_epdg_gsup_response_t*, private_osmo_epdg_gsup_client_t *this, char *imsi, uint8_t cn_domain, chunk_t *auts, chunk_t *auts_rand) { @@ -489,6 +530,7 @@ osmo_epdg_gsup_client_t *osmo_epdg_gsup_client_create(char *uri) .public = { .send_auth_request = _send_auth_request, .update_location = _update_location, + .tunnel_request = _tunnel_request, .destroy = _destroy, }, .uri = strdup(uri), diff --git a/src/libcharon/plugins/osmo_epdg/gsup_client.h b/src/libcharon/plugins/osmo_epdg/gsup_client.h index 62d039e67..5ee5ac348 100644 --- a/src/libcharon/plugins/osmo_epdg/gsup_client.h +++ b/src/libcharon/plugins/osmo_epdg/gsup_client.h @@ -61,6 +61,14 @@ struct osmo_epdg_gsup_client_t { char *imsi, uint8_t cn_domain); + /** + * Tunnel Request + * + * @return NULL or the osmo_gsup_message + */ + osmo_epdg_gsup_response_t *(*tunnel_request)(osmo_epdg_gsup_client_t *this, + char *imsi, char *apn); + /** * Destroy a osmo_epdg_gsup_client_t. */ diff --git a/src/libcharon/plugins/osmo_epdg/osmo_epdg_listener.c b/src/libcharon/plugins/osmo_epdg/osmo_epdg_listener.c index 25f089ba9..43fd04db8 100644 --- a/src/libcharon/plugins/osmo_epdg/osmo_epdg_listener.c +++ b/src/libcharon/plugins/osmo_epdg/osmo_epdg_listener.c @@ -89,12 +89,34 @@ METHOD(listener_t, authorize, bool, ike_sa->get_name(ike_sa), final, ike_sa->has_condition(ike_sa, COND_EAP_AUTHENTICATED)); - - sleep(1); - if (final) + + if (!final) { - /* TODO: create new Tunnel and save Tunnel information locally */ + return TRUE; } + + osmo_epdg_gsup_response_t *resp = this->gsup->tunnel_request(this->gsup, imsi, apn); + if (!resp) + { + DBG1(DBG_NET, "epdg: GSUP: couldn't send Tunnel Requeset."); + goto err; + } + + if (resp->gsup.message_type == OSMO_GSUP_MSGT_EPDG_TUNNEL_ERROR) + { + DBG1(DBG_NET, "epdg_listener: Tunnel Error! Cause: %02x", resp->gsup.cause); + goto err; + } + else if (resp->gsup.message_type != OSMO_GSUP_MSGT_EPDG_TUNNEL_RESULT) + { + DBG1(DBG_NET, "epdg_listener: Tunnel unexpected message type: %02x", resp->gsup.message_type); + goto err; + } + + return TRUE; +err: + *success = FALSE; + /* keep still subscribed */ return TRUE; } diff --git a/src/libcharon/plugins/osmo_epdg/osmo_epdg_utils.c b/src/libcharon/plugins/osmo_epdg/osmo_epdg_utils.c index c3827203a..f2301dd4e 100644 --- a/src/libcharon/plugins/osmo_epdg/osmo_epdg_utils.c +++ b/src/libcharon/plugins/osmo_epdg/osmo_epdg_utils.c @@ -19,6 +19,7 @@ #include #include +#include #include #include @@ -63,3 +64,24 @@ int get_imsi(identification_t *id, char *imsi, size_t imsi_len) strncpy(imsi, nai.ptr + 1, min(15, imsi_len)); return 0; } + +int get_apn(ike_sa_t *sa, char *apn, size_t apn_len) +{ + identification_t* apn_id; + chunk_t apn_chunk; + + apn_id = sa->get_my_id(sa); + if (!apn_id) + { + return -EINVAL; + } + + apn_chunk = apn_id->get_encoding(apn_id); + if (apn_chunk.len >= apn_len) + { + return -ENOMEM; + } + + strncpy(apn, apn_chunk.ptr, apn_len); + return -1; +} diff --git a/src/libcharon/plugins/osmo_epdg/osmo_epdg_utils.h b/src/libcharon/plugins/osmo_epdg/osmo_epdg_utils.h index dbf9d54c3..57c027aca 100644 --- a/src/libcharon/plugins/osmo_epdg/osmo_epdg_utils.h +++ b/src/libcharon/plugins/osmo_epdg/osmo_epdg_utils.h @@ -17,6 +17,7 @@ */ #include +#include #include #include @@ -25,3 +26,4 @@ struct msgb *chunk_to_msgb(chunk_t *chunk); int get_imsi(identification_t *id, char *imsi, size_t imsi_len); +int get_apn(ike_sa_t *sa, char *apn, size_t apn_len);