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
next prev 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox