/*
 * Example application using RADIUS client as a library
 * Copyright (c) 2007, Jouni Malinen <j@w1.fi>
 *
 * This software may be distributed under the terms of the BSD license.
 * See README for more details.
 */

#include "includes.h"

#include "common.h"
#include "eloop.h"
#include "radius/radius.h"
#include "radius/radius_client.h"

extern int wpa_debug_level;

struct radius_ctx {
	struct radius_client_data *radius;
	struct hostapd_radius_servers conf;
	u8 radius_identifier;
	struct in_addr own_ip_addr;
};


static void hostapd_logger_cb(void *ctx, const u8 *addr, unsigned int module,
			      int level, const char *txt, size_t len)
{
	printf("%s\n", txt);
}


/* Process the RADIUS frames from Authentication Server */
static RadiusRxResult receive_auth(struct radius_msg *msg,
				   struct radius_msg *req,
				   const u8 *shared_secret,
				   size_t shared_secret_len,
				   void *data)
{
	/* struct radius_ctx *ctx = data; */
	printf("Received RADIUS Authentication message; code=%d\n",
	       radius_msg_get_hdr(msg)->code);

	/* We're done for this example, so request eloop to terminate. */
	eloop_terminate();

	return RADIUS_RX_PROCESSED;
}


static void start_example(void *eloop_ctx, void *timeout_ctx)
{
	struct radius_ctx *ctx = eloop_ctx;
	struct radius_msg *msg;

	printf("Sending a RADIUS authentication message\n");

	ctx->radius_identifier = radius_client_get_id(ctx->radius);
	msg = radius_msg_new(RADIUS_CODE_ACCESS_REQUEST,
			     ctx->radius_identifier);
	if (msg == NULL) {
		printf("Could not create net RADIUS packet\n");
		return;
	}

	radius_msg_make_authenticator(msg, (u8 *) ctx, sizeof(*ctx));

	if (!radius_msg_add_attr(msg, RADIUS_ATTR_USER_NAME,
				 (u8 *) "user", 4)) {
		printf("Could not add User-Name\n");
		radius_msg_free(msg);
		return;
	}

	if (!radius_msg_add_attr_user_password(
		    msg, (u8 *) "password", 8,
		    ctx->conf.auth_server->shared_secret,
		    ctx->conf.auth_server->shared_secret_len)) {
		printf("Could not add User-Password\n");
		radius_msg_free(msg);
		return;
	}

	if (!radius_msg_add_attr(msg, RADIUS_ATTR_NAS_IP_ADDRESS,
				 (u8 *) &ctx->own_ip_addr, 4)) {
		printf("Could not add NAS-IP-Address\n");
		radius_msg_free(msg);
		return;
	}

	if (radius_client_send(ctx->radius, msg, RADIUS_AUTH, NULL) < 0)
		radius_msg_free(msg);
}


int main(int argc, char *argv[])
{
	struct radius_ctx ctx;
	struct hostapd_radius_server *srv;

	if (os_program_init())
		return -1;

	hostapd_logger_register_cb(hostapd_logger_cb);

	os_memset(&ctx, 0, sizeof(ctx));
	inet_aton("127.0.0.1", &ctx.own_ip_addr);

	if (eloop_init()) {
		printf("Failed to initialize event loop\n");
		return -1;
	}

	srv = os_zalloc(sizeof(*srv));
	if (srv == NULL)
		return -1;

	srv->addr.af = AF_INET;
	srv->port = 1812;
	if (hostapd_parse_ip_addr("127.0.0.1", &srv->addr) < 0) {
		printf("Failed to parse IP address\n");
		return -1;
	}
	srv->shared_secret = (u8 *) os_strdup("radius");
	srv->shared_secret_len = 6;

	ctx.conf.auth_server = ctx.conf.auth_servers = srv;
	ctx.conf.num_auth_servers = 1;
	ctx.conf.msg_dumps = 1;

	ctx.radius = radius_client_init(&ctx, &ctx.conf);
	if (ctx.radius == NULL) {
		printf("Failed to initialize RADIUS client\n");
		return -1;
	}

	if (radius_client_register(ctx.radius, RADIUS_AUTH, receive_auth,
				   &ctx) < 0) {
		printf("Failed to register RADIUS authentication handler\n");
		return -1;
	}

	eloop_register_timeout(0, 0, start_example, &ctx, NULL);

	eloop_run();

	radius_client_deinit(ctx.radius);
	os_free(srv->shared_secret);
	os_free(srv);

	eloop_destroy();
	os_program_deinit();

	return 0;
}
