All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kristen Carlson Accardi <kristen@linux.intel.com>
To: ofono@ofono.org
Subject: [PATCH 4/6] CHAP with MD5 authentication support
Date: Mon, 22 Mar 2010 17:05:59 -0700	[thread overview]
Message-ID: <1269302761-20125-5-git-send-email-kristen@linux.intel.com> (raw)
In-Reply-To: <1269302761-20125-1-git-send-email-kristen@linux.intel.com>

[-- Attachment #1: Type: text/plain, Size: 9497 bytes --]

Authentication support with CHAP and MD5
---
 Makefile.am        |    3 +-
 gatchat/gatppp.c   |   11 +++-
 gatchat/gatppp.h   |    2 +
 gatchat/ppp.c      |    1 +
 gatchat/ppp.h      |   15 ++++
 gatchat/ppp_auth.c |  229 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 259 insertions(+), 2 deletions(-)
 create mode 100644 gatchat/ppp_auth.c

diff --git a/Makefile.am b/Makefile.am
index 1a444ca..df89ef5 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -58,7 +58,8 @@ gatchat_sources = gatchat/gatchat.h gatchat/gatchat.c \
 				gatchat/gatserver.h gatchat/gatserver.c \
 				gatchat/gatppp.c gatchat/gatppp.h \
 				gatchat/ppp.c gatchat/ppp.h gatchat/ppp_cp.h \
-				gatchat/ppp_cp.c gatchat/ppp_lcp.c
+				gatchat/ppp_cp.c gatchat/ppp_lcp.c \
+				gatchat/ppp_auth.c
 
 udev_files = plugins/ofono.rules
 
diff --git a/gatchat/gatppp.c b/gatchat/gatppp.c
index f083842..2b682f8 100644
--- a/gatchat/gatppp.c
+++ b/gatchat/gatppp.c
@@ -43,6 +43,12 @@ void g_at_ppp_open(GAtPPP *ppp)
 	lcp_open(ppp->lcp);
 }
 
+void g_at_ppp_set_credentials(GAtPPP *ppp, const char *username,
+				const char *passwd)
+{
+	auth_set_credentials(ppp->auth, username, passwd);
+}
+
 void g_at_ppp_set_connect_function(GAtPPP *ppp,
 			       GAtPPPConnectFunc callback, gpointer user_data)
 {
@@ -73,6 +79,9 @@ void g_at_ppp_shutdown(GAtPPP *ppp)
 
 	/* remove lcp */
 	lcp_free(ppp->lcp);
+
+	/* remove auth */
+	auth_free(ppp->auth);
 }
 
 void g_at_ppp_ref(GAtPPP *ppp)
@@ -124,7 +133,7 @@ GAtPPP *g_at_ppp_new(GIOChannel *modem)
 	ppp->lcp = lcp_new(ppp);
 
 	/* initialize the autentication state */
-
+	ppp->auth = auth_new(ppp);
 
 	/* intialize the network state */
 
diff --git a/gatchat/gatppp.h b/gatchat/gatppp.h
index 0d5d5cc..8db26c9 100644
--- a/gatchat/gatppp.h
+++ b/gatchat/gatppp.h
@@ -51,6 +51,8 @@ void g_at_ppp_set_disconnect_function(GAtPPP *ppp,
 void g_at_ppp_shutdown(GAtPPP *ppp);
 void g_at_ppp_ref(GAtPPP *ppp);
 void g_at_ppp_unref(GAtPPP *ppp);
+void g_at_ppp_set_credentials(GAtPPP *ppp, const char *username,
+				const char *passwd);
 #ifdef __cplusplus
 }
 #endif
diff --git a/gatchat/ppp.c b/gatchat/ppp.c
index 2399ed4..0b3221b 100644
--- a/gatchat/ppp.c
+++ b/gatchat/ppp.c
@@ -463,6 +463,7 @@ void ppp_set_auth(GAtPPP *ppp, guint8* auth_data)
 	switch (proto) {
 	case CHAP_PROTOCOL:
 		/* get the algorithm */
+		auth_set_proto(ppp->auth, proto, auth_data[2]);
 		break;
 	default:
 		g_printerr("unknown authentication proto\n");
diff --git a/gatchat/ppp.h b/gatchat/ppp.h
index 7753a39..53d5274 100644
--- a/gatchat/ppp.h
+++ b/gatchat/ppp.h
@@ -95,10 +95,20 @@ static inline guint16 __get_unaligned_short(const gpointer p)
 #define ppp_proto(packet) \
 	(get_host_short(packet + 2))
 
+struct auth_data {
+	guint16 proto;
+	gpointer proto_data;
+	void (*process_packet)(struct auth_data *data, guint8 *packet);
+	char *username;
+	char *passwd;
+	GAtPPP *ppp;
+};
+
 struct _GAtPPP {
 	gint ref_count;
 	enum ppp_phase phase;
 	struct pppcp_data *lcp;
+	struct auth_data *auth;
 	guint8 buffer[BUFFERSZ];
 	int index;
 	gint mru;
@@ -137,3 +147,8 @@ void lcp_open(struct pppcp_data *data);
 void lcp_close(struct pppcp_data *data);
 void lcp_establish(struct pppcp_data *data);
 void lcp_terminate(struct pppcp_data *data);
+void auth_set_credentials(struct auth_data *data, const char *username,
+				const char *passwd);
+void auth_set_proto(struct auth_data *data, guint16 proto, guint8 method);
+struct auth_data *auth_new(GAtPPP *ppp);
+void auth_free(struct auth_data *auth);
diff --git a/gatchat/ppp_auth.c b/gatchat/ppp_auth.c
new file mode 100644
index 0000000..c23d9ad
--- /dev/null
+++ b/gatchat/ppp_auth.c
@@ -0,0 +1,229 @@
+/*
+ *
+ *  PPP library with GLib integration
+ *
+ *  Copyright (C) 2009-2010  Intel Corporation. All rights reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <termios.h>
+#include <arpa/inet.h>
+
+#include <glib.h>
+
+#include "gatppp.h"
+#include "ppp.h"
+
+struct chap_header {
+	guint8 code;
+	guint8 identifier;
+	guint16 length;
+	guint8 data[0];
+} __attribute__((packed));
+
+struct chap_data {
+	guint8 method;
+	struct auth_data *auth;
+};
+
+enum chap_code {
+	CHALLENGE=1,
+	RESPONSE,
+	SUCCESS,
+	FAILURE
+};
+
+void auth_set_credentials(struct auth_data *data, const char *username,
+				const char *passwd)
+{
+	if (data == NULL)
+		return;
+
+	if (data->username)
+		g_free(data->username);
+	if (data->passwd)
+		g_free(data->passwd);
+
+	data->username = g_strdup(username);
+	data->passwd = g_strdup(passwd);
+}
+
+static void chap_process_challenge(struct auth_data *auth, guint8 *packet)
+{
+	struct chap_header *header = (struct chap_header *) packet;
+	struct chap_header *response;
+	struct chap_data *data = auth->proto_data;
+	GChecksum *checksum;
+	gchar *secret = data->auth->passwd;
+	guint16 response_length;
+	struct ppp_header *ppp_packet;
+	gsize digest_len;
+
+	/* create a checksum over id, secret, and challenge */
+	checksum = g_checksum_new(data->method);
+	if (!checksum)
+		return;
+	g_checksum_update(checksum, &header->identifier, 1);
+	g_checksum_update(checksum, (guchar *) secret, strlen(secret));
+	g_checksum_update(checksum, &header->data[1], header->data[0]);
+
+	/* transmit a response packet */
+	/*
+	 * allocate space for the header, the checksum, and the ppp header,
+	 * and the value size byte
+	 */
+	digest_len = g_checksum_type_get_length(data->method);
+	response_length = digest_len + sizeof(*header) + 1;
+	ppp_packet = g_try_malloc0(response_length + 2);
+	if (!ppp_packet)
+		goto challenge_out;
+
+	/* add our protocol information */
+	ppp_packet->proto = htons(CHAP_PROTOCOL);
+	response = (struct chap_header *) &ppp_packet->info;
+	if (response) {
+		response->code = RESPONSE;
+		response->identifier = header->identifier;
+		response->length = htons(response_length);
+		response->data[0] = digest_len;
+		g_checksum_get_digest(checksum, &response->data[1],
+					(gsize *) &response->data[0]);
+		/* leave the name empty? */
+	}
+
+	/* transmit the packet */
+	ppp_transmit(auth->ppp, (guint8 *) ppp_packet, response_length);
+
+challenge_out:
+	g_checksum_free(checksum);
+}
+
+static void chap_process_success(struct auth_data *data, guint8 *packet)
+{
+	ppp_generate_event(data->ppp, PPP_SUCCESS);
+}
+
+static void chap_process_failure(struct auth_data *data, guint8 *packet)
+{
+	struct chap_header *header = (struct chap_header *) packet;
+
+	g_print("Failed to authenticate, message %s\n", header->data);
+}
+
+/*
+ * parse the packet
+ */
+static void chap_process_packet(gpointer priv, guint8 *new_packet)
+{
+	struct auth_data *data = priv;
+	guint8 code = new_packet[0];
+
+	switch (code) {
+	case CHALLENGE:
+		chap_process_challenge(data, new_packet);
+		break;
+	case RESPONSE:
+		g_print("Oops, received RESPONSE, but I've not implemented\n");
+		break;
+	case SUCCESS:
+		chap_process_success(data, new_packet);
+		break;
+	case FAILURE:
+		chap_process_failure(data, new_packet);
+		break;
+	default:
+		g_print("unknown auth code\n");
+		break;
+	}
+}
+
+struct ppp_packet_handler chap_packet_handler = {
+	.proto = CHAP_PROTOCOL,
+	.handler = chap_process_packet,
+};
+
+static void chap_free(struct auth_data *auth)
+{
+	/* TBD unregister protocol handler */
+
+	g_free(auth->proto_data);
+}
+
+static struct chap_data *chap_new(struct auth_data *auth, guint8 method)
+{
+	struct chap_data *data;
+
+	data = g_try_malloc0(sizeof(*data));
+	if (!data)
+		return NULL;
+
+	data->auth = auth;
+	switch (method) {
+	case MD5:
+		data->method = G_CHECKSUM_MD5;
+		break;
+	default:
+		g_print("Unknown method\n");
+	}
+
+	/* register packet handler for CHAP protocol */
+	chap_packet_handler.priv = auth;
+	ppp_register_packet_handler(&chap_packet_handler);
+	return data;
+}
+
+void auth_set_proto(struct auth_data *data, guint16 proto, guint8 method)
+{
+	if (data == NULL)
+		return;
+
+	switch (proto) {
+	case CHAP_PROTOCOL:
+		data->proto_data = (gpointer) chap_new(data, method);
+		break;
+	default:
+		g_print("Unknown auth protocol 0x%x\n", proto);
+	}
+}
+
+void auth_free(struct auth_data *data)
+{
+	if (data == NULL)
+		return;
+
+	chap_free(data);
+	g_free(data);
+}
+
+struct auth_data *auth_new(GAtPPP *ppp)
+{
+	struct auth_data *data;
+
+	data = g_try_malloc0(sizeof(*data));
+	if (!data)
+		return NULL;
+
+	data->ppp = ppp;
+	return data;
+}
-- 
1.6.6.1


  parent reply	other threads:[~2010-03-23  0:05 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-03-23  0:05 [PATCH 0/6] PPP Patches v3 Kristen Carlson Accardi
2010-03-23  0:05 ` [PATCH 1/6] Basic PPP protocol support Kristen Carlson Accardi
2010-03-23  0:05 ` [PATCH 2/6] Generic PPP control " Kristen Carlson Accardi
2010-03-23  0:05 ` [PATCH 3/6] PPP LCP support Kristen Carlson Accardi
2010-03-23  0:05 ` Kristen Carlson Accardi [this message]
2010-03-23  0:06 ` [PATCH 5/6] IP support for PPP Kristen Carlson Accardi
2010-03-23  0:06 ` [PATCH 6/6] Add PPP option to gsmdial Kristen Carlson Accardi
2010-03-23  5:30   ` Gustavo F. Padovan
2010-03-23  6:30     ` Marcel Holtmann
2010-03-23  0:32 ` [PATCH 0/6] PPP Patches v3 Marcel Holtmann
2010-03-23  2:22   ` Marcel Holtmann
2010-03-23  3:22     ` Kristen Carlson Accardi
2010-03-23  3:47       ` Marcel Holtmann
2010-03-23  4:07         ` Kristen Carlson Accardi
2010-03-23  4:51           ` Marcel Holtmann
2010-03-23  6:14             ` Kristen Carlson Accardi
2010-03-23  6:45               ` Marcel Holtmann
2010-03-23 17:16                 ` Kristen Carlson Accardi
2010-03-23 17:34                 ` Kristen Carlson Accardi
2010-03-23 17:56                   ` Marcel Holtmann
2010-03-23 18:26                     ` Kristen Carlson Accardi
2010-03-23 18:37                       ` Denis Kenzior
2010-03-23 19:07                       ` Marcel Holtmann
2010-03-23  3:56       ` Kristen Carlson Accardi
2010-03-23 12:34     ` =?unknown-8bit?q?R=C3=A9mi?= Denis-Courmont
2010-03-23 12:49       ` Marcel Holtmann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1269302761-20125-5-git-send-email-kristen@linux.intel.com \
    --to=kristen@linux.intel.com \
    --cc=ofono@ofono.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.