3 * PPP library with GLib integration
5 * Copyright (C) 2009-2011 Intel Corporation. All rights reserved.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
31 #include <arpa/inet.h>
43 } __attribute__((packed));
57 static void chap_process_challenge(struct ppp_chap *chap, const guint8 *packet)
59 const struct chap_header *header = (const struct chap_header *) packet;
60 struct chap_header *response;
62 const char *secret = g_at_ppp_get_password(chap->ppp);
63 const char *username = g_at_ppp_get_username(chap->ppp);
64 guint16 response_length;
65 struct ppp_header *ppp_packet;
68 /* create a checksum over id, secret, and challenge */
69 checksum = g_checksum_new(chap->method);
73 g_checksum_update(checksum, &header->identifier, 1);
76 g_checksum_update(checksum, (guchar *) secret, strlen(secret));
78 g_checksum_update(checksum, &header->data[1], header->data[0]);
80 /* transmit a response packet */
82 * allocate space for the header, the checksum, and the ppp header,
83 * and the value size byte
85 digest_len = g_checksum_type_get_length(chap->method);
86 response_length = digest_len + sizeof(*header) + 1;
89 response_length += strlen(username);
91 ppp_packet = ppp_packet_new(response_length, CHAP_PROTOCOL);
92 if (ppp_packet == NULL)
95 response = (struct chap_header *) &ppp_packet->info;
97 response->code = RESPONSE;
98 response->identifier = header->identifier;
99 response->length = htons(response_length);
100 g_checksum_get_digest(checksum, response->data + 1,
102 response->data[0] = digest_len;
103 /* leave the name empty? */
106 if (username != NULL)
107 memcpy(response->data + digest_len + 1, username,
110 /* transmit the packet */
111 ppp_transmit(chap->ppp, (guint8 *) ppp_packet, response_length);
115 g_checksum_free(checksum);
121 void ppp_chap_process_packet(struct ppp_chap *chap, const guint8 *new_packet,
126 if (len < sizeof(struct chap_header))
129 code = new_packet[0];
133 chap_process_challenge(chap, new_packet);
138 ppp_auth_notify(chap->ppp, TRUE);
141 ppp_auth_notify(chap->ppp, FALSE);
148 void ppp_chap_free(struct ppp_chap *chap)
153 struct ppp_chap *ppp_chap_new(GAtPPP *ppp, guint8 method)
155 struct ppp_chap *chap;
160 chap = g_try_new0(struct ppp_chap, 1);
165 chap->method = G_CHECKSUM_MD5;