char imsi[20];
enum { PENDING, SUCCESS, FAILURE } state;
void *cb_session_ctx;
- struct os_time timestamp;
int aka;
union {
struct {
}
-static struct eap_sim_pseudonym *
+static char *
db_get_pseudonym(struct eap_sim_db_data *data, const char *pseudonym)
{
char cmd[128];
if (!valid_db_string(pseudonym))
return NULL;
- os_memset(&data->db_tmp_pseudonym, 0, sizeof(data->db_tmp_pseudonym));
- os_strlcpy(data->db_tmp_pseudonym_str, pseudonym,
- sizeof(data->db_tmp_pseudonym_str));
- data->db_tmp_pseudonym.pseudonym = data->db_tmp_pseudonym_str;
+ os_memset(&data->db_tmp_identity, 0, sizeof(data->db_tmp_identity));
os_snprintf(cmd, sizeof(cmd),
"SELECT permanent FROM pseudonyms WHERE pseudonym='%s';",
pseudonym);
if (sqlite3_exec(data->sqlite_db, cmd, get_pseudonym_cb, data, NULL) !=
SQLITE_OK)
return NULL;
- if (data->db_tmp_pseudonym.permanent == NULL)
+ if (data->db_tmp_identity[0] == '\0')
return NULL;
- return &data->db_tmp_pseudonym;
+ return data->db_tmp_identity;
}
char buf[1000], *pos, *cmd, *imsi;
int res;
- res = recv(sock, buf, sizeof(buf), 0);
+ res = recv(sock, buf, sizeof(buf) - 1, 0);
if (res < 0)
return;
+ buf[res] = '\0';
wpa_hexdump_ascii_key(MSG_MSGDUMP, "EAP-SIM DB: Received from an "
"external source", (u8 *) buf, res);
if (res == 0)
return;
- if (res >= (int) sizeof(buf))
- res = sizeof(buf) - 1;
- buf[res] = '\0';
if (data->get_complete_cb == NULL) {
wpa_printf(MSG_DEBUG, "EAP-SIM DB: No get_complete_cb "
data->sock = socket(PF_UNIX, SOCK_DGRAM, 0);
if (data->sock < 0) {
- perror("socket(eap_sim_db)");
+ wpa_printf(MSG_INFO, "socket(eap_sim_db): %s", strerror(errno));
return -1;
}
"/tmp/eap_sim_db_%d-%d", getpid(), counter++);
os_free(data->local_sock);
data->local_sock = os_strdup(addr.sun_path);
+ if (data->local_sock == NULL) {
+ close(data->sock);
+ data->sock = -1;
+ return -1;
+ }
if (bind(data->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
- perror("bind(eap_sim_db)");
+ wpa_printf(MSG_INFO, "bind(eap_sim_db): %s", strerror(errno));
close(data->sock);
data->sock = -1;
return -1;
addr.sun_family = AF_UNIX;
os_strlcpy(addr.sun_path, data->fname + 5, sizeof(addr.sun_path));
if (connect(data->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
- perror("connect(eap_sim_db)");
+ wpa_printf(MSG_INFO, "connect(eap_sim_db): %s",
+ strerror(errno));
wpa_hexdump_ascii(MSG_INFO, "HLR/AuC GW socket",
(u8 *) addr.sun_path,
os_strlen(addr.sun_path));
close(data->sock);
data->sock = -1;
+ unlink(data->local_sock);
+ os_free(data->local_sock);
+ data->local_sock = NULL;
return -1;
}
* @ctx: Context pointer for get_complete_cb
* Returns: Pointer to a private data structure or %NULL on failure
*/
-void * eap_sim_db_init(const char *config,
- void (*get_complete_cb)(void *ctx, void *session_ctx),
- void *ctx)
+struct eap_sim_db_data *
+eap_sim_db_init(const char *config,
+ void (*get_complete_cb)(void *ctx, void *session_ctx),
+ void *ctx)
{
struct eap_sim_db_data *data;
char *pos;
if (send(data->sock, msg, len, 0) < 0) {
_errno = errno;
- perror("send[EAP-SIM DB UNIX]");
+ wpa_printf(MSG_INFO, "send[EAP-SIM DB UNIX]: %s",
+ strerror(errno));
}
if (_errno == ENOTCONN || _errno == EDESTADDRREQ || _errno == EINVAL ||
wpa_printf(MSG_DEBUG, "EAP-SIM DB: Reconnected to the "
"external server");
if (send(data->sock, msg, len, 0) < 0) {
- perror("send[EAP-SIM DB UNIX]");
+ wpa_printf(MSG_INFO, "send[EAP-SIM DB UNIX]: %s",
+ strerror(errno));
return -1;
}
}
/**
* eap_sim_db_get_gsm_triplets - Get GSM triplets
- * @priv: Private data pointer from eap_sim_db_init()
+ * @data: Private data pointer from eap_sim_db_init()
* @username: Permanent username (prefix | IMSI)
* @max_chal: Maximum number of triplets
* @_rand: Buffer for RAND values
* function will then be called again and the newly received triplets will then
* be given to the caller.
*/
-int eap_sim_db_get_gsm_triplets(void *priv, const char *username, int max_chal,
+int eap_sim_db_get_gsm_triplets(struct eap_sim_db_data *data,
+ const char *username, int max_chal,
u8 *_rand, u8 *kc, u8 *sres,
void *cb_session_ctx)
{
- struct eap_sim_db_data *data = priv;
struct eap_sim_db_pending *entry;
int len, ret;
char msg[40];
os_memcpy(msg + len, imsi, imsi_len);
len += imsi_len;
ret = os_snprintf(msg + len, sizeof(msg) - len, " %d", max_chal);
- if (ret < 0 || (size_t) ret >= sizeof(msg) - len)
+ if (os_snprintf_error(sizeof(msg) - len, ret))
return EAP_SIM_DB_FAILURE;
len += ret;
if (entry == NULL)
return EAP_SIM_DB_FAILURE;
- os_get_time(&entry->timestamp);
os_strlcpy(entry->imsi, imsi, sizeof(entry->imsi));
entry->cb_session_ctx = cb_session_ctx;
entry->state = PENDING;
}
-static struct eap_sim_pseudonym *
-eap_sim_db_get_pseudonym(struct eap_sim_db_data *data, const char *pseudonym)
-{
- struct eap_sim_pseudonym *p;
-
- if (pseudonym[0] != EAP_SIM_PSEUDONYM_PREFIX &&
- pseudonym[0] != EAP_AKA_PSEUDONYM_PREFIX &&
- pseudonym[0] != EAP_AKA_PRIME_PSEUDONYM_PREFIX)
- return NULL;
-
-#ifdef CONFIG_SQLITE
- if (data->sqlite_db)
- return db_get_pseudonym(data, pseudonym);
-#endif /* CONFIG_SQLITE */
-
- p = data->pseudonyms;
- while (p) {
- if (os_strcmp(p->pseudonym, pseudonym) == 0)
- return p;
- p = p->next;
- }
-
- return NULL;
-}
-
-
-static struct eap_sim_reauth *
-eap_sim_db_get_reauth(struct eap_sim_db_data *data, const char *reauth_id)
-{
- struct eap_sim_reauth *r;
-
- if (reauth_id[0] != EAP_SIM_REAUTH_ID_PREFIX &&
- reauth_id[0] != EAP_AKA_REAUTH_ID_PREFIX &&
- reauth_id[0] != EAP_AKA_PRIME_REAUTH_ID_PREFIX)
- return NULL;
-
-#ifdef CONFIG_SQLITE
- if (data->sqlite_db)
- return db_get_reauth(data, reauth_id);
-#endif /* CONFIG_SQLITE */
-
- r = data->reauths;
- while (r) {
- if (os_strcmp(r->reauth_id, reauth_id) == 0)
- break;
- r = r->next;
- }
-
- return r;
-}
-
-
static char * eap_sim_db_get_next(struct eap_sim_db_data *data, char prefix)
{
char *id, *pos, *end;
pos = id;
end = id + sizeof(buf) * 2 + 2;
*pos++ = prefix;
- pos += wpa_snprintf_hex(pos, end - pos, buf, sizeof(buf));
+ wpa_snprintf_hex(pos, end - pos, buf, sizeof(buf));
return id;
}
/**
* eap_sim_db_get_next_pseudonym - EAP-SIM DB: Get next pseudonym
- * @priv: Private data pointer from eap_sim_db_init()
+ * @data: Private data pointer from eap_sim_db_init()
* @method: EAP method (SIM/AKA/AKA')
* Returns: Next pseudonym (allocated string) or %NULL on failure
*
* with eap_sim_db_add_pseudonym() once the authentication has been completed
* successfully. Caller is responsible for freeing the returned buffer.
*/
-char * eap_sim_db_get_next_pseudonym(void *priv, enum eap_sim_db_method method)
+char * eap_sim_db_get_next_pseudonym(struct eap_sim_db_data *data,
+ enum eap_sim_db_method method)
{
- struct eap_sim_db_data *data = priv;
char prefix = EAP_SIM_REAUTH_ID_PREFIX;
switch (method) {
/**
* eap_sim_db_get_next_reauth_id - EAP-SIM DB: Get next reauth_id
- * @priv: Private data pointer from eap_sim_db_init()
+ * @data: Private data pointer from eap_sim_db_init()
* @method: EAP method (SIM/AKA/AKA')
* Returns: Next reauth_id (allocated string) or %NULL on failure
*
* has been completed successfully. Caller is responsible for freeing the
* returned buffer.
*/
-char * eap_sim_db_get_next_reauth_id(void *priv, enum eap_sim_db_method method)
+char * eap_sim_db_get_next_reauth_id(struct eap_sim_db_data *data,
+ enum eap_sim_db_method method)
{
- struct eap_sim_db_data *data = priv;
char prefix = EAP_SIM_REAUTH_ID_PREFIX;
switch (method) {
/**
* eap_sim_db_add_pseudonym - EAP-SIM DB: Add new pseudonym
- * @priv: Private data pointer from eap_sim_db_init()
+ * @data: Private data pointer from eap_sim_db_init()
* @permanent: Permanent username
* @pseudonym: Pseudonym for this user. This needs to be an allocated buffer,
* e.g., return value from eap_sim_db_get_next_pseudonym(). Caller must not
* This function adds a new pseudonym for EAP-SIM user. EAP-SIM DB is
* responsible of freeing pseudonym buffer once it is not needed anymore.
*/
-int eap_sim_db_add_pseudonym(void *priv, const char *permanent,
- char *pseudonym)
+int eap_sim_db_add_pseudonym(struct eap_sim_db_data *data,
+ const char *permanent, char *pseudonym)
{
- struct eap_sim_db_data *data = priv;
struct eap_sim_pseudonym *p;
wpa_printf(MSG_DEBUG, "EAP-SIM DB: Add pseudonym '%s' for permanent "
"username '%s'", pseudonym, permanent);
* EAP-SIM DB is responsible of freeing reauth_id buffer once it is not needed
* anymore.
*/
-int eap_sim_db_add_reauth(void *priv, const char *permanent, char *reauth_id,
- u16 counter, const u8 *mk)
+int eap_sim_db_add_reauth(struct eap_sim_db_data *data, const char *permanent,
+ char *reauth_id, u16 counter, const u8 *mk)
{
- struct eap_sim_db_data *data = priv;
struct eap_sim_reauth *r;
+ wpa_printf(MSG_DEBUG, "EAP-SIM DB: Add reauth_id '%s' for permanent "
+ "identity '%s'", reauth_id, permanent);
+
#ifdef CONFIG_SQLITE
if (data->sqlite_db)
return db_add_reauth(data, permanent, reauth_id, counter, mk,
#ifdef EAP_SERVER_AKA_PRIME
/**
* eap_sim_db_add_reauth_prime - EAP-AKA' DB: Add new re-authentication entry
- * @priv: Private data pointer from eap_sim_db_init()
+ * @data: Private data pointer from eap_sim_db_init()
* @permanent: Permanent username
* @reauth_id: reauth_id for this user. This needs to be an allocated buffer,
* e.g., return value from eap_sim_db_get_next_reauth_id(). Caller must not
* EAP-SIM DB is responsible of freeing reauth_id buffer once it is not needed
* anymore.
*/
-int eap_sim_db_add_reauth_prime(void *priv, const char *permanent,
- char *reauth_id, u16 counter, const u8 *k_encr,
+int eap_sim_db_add_reauth_prime(struct eap_sim_db_data *data,
+ const char *permanent, char *reauth_id,
+ u16 counter, const u8 *k_encr,
const u8 *k_aut, const u8 *k_re)
{
- struct eap_sim_db_data *data = priv;
struct eap_sim_reauth *r;
wpa_printf(MSG_DEBUG, "EAP-SIM DB: Add reauth_id '%s' for permanent "
/**
* eap_sim_db_get_permanent - EAP-SIM DB: Get permanent identity
- * @priv: Private data pointer from eap_sim_db_init()
+ * @data: Private data pointer from eap_sim_db_init()
* @pseudonym: Pseudonym username
* Returns: Pointer to permanent username or %NULL if not found
*/
-const char * eap_sim_db_get_permanent(void *priv, const char *pseudonym)
+const char *
+eap_sim_db_get_permanent(struct eap_sim_db_data *data, const char *pseudonym)
{
- struct eap_sim_db_data *data = priv;
struct eap_sim_pseudonym *p;
- if (pseudonym == NULL)
- return NULL;
+#ifdef CONFIG_SQLITE
+ if (data->sqlite_db)
+ return db_get_pseudonym(data, pseudonym);
+#endif /* CONFIG_SQLITE */
- p = eap_sim_db_get_pseudonym(data, pseudonym);
- if (p == NULL)
- return NULL;
+ p = data->pseudonyms;
+ while (p) {
+ if (os_strcmp(p->pseudonym, pseudonym) == 0)
+ return p->permanent;
+ p = p->next;
+ }
- return p->permanent;
+ return NULL;
}
/**
* eap_sim_db_get_reauth_entry - EAP-SIM DB: Get re-authentication entry
- * @priv: Private data pointer from eap_sim_db_init()
+ * @data: Private data pointer from eap_sim_db_init()
* @reauth_id: Fast re-authentication username
* Returns: Pointer to the re-auth entry, or %NULL if not found
*/
struct eap_sim_reauth *
-eap_sim_db_get_reauth_entry(void *priv, const char *reauth_id)
+eap_sim_db_get_reauth_entry(struct eap_sim_db_data *data,
+ const char *reauth_id)
{
- struct eap_sim_db_data *data = priv;
struct eap_sim_reauth *r;
- if (reauth_id == NULL)
- return NULL;
- r = eap_sim_db_get_reauth(data, reauth_id);
+#ifdef CONFIG_SQLITE
+ if (data->sqlite_db)
+ return db_get_reauth(data, reauth_id);
+#endif /* CONFIG_SQLITE */
+
+ r = data->reauths;
+ while (r) {
+ if (os_strcmp(r->reauth_id, reauth_id) == 0)
+ break;
+ r = r->next;
+ }
+
return r;
}
/**
* eap_sim_db_remove_reauth - EAP-SIM DB: Remove re-authentication entry
- * @priv: Private data pointer from eap_sim_db_init()
+ * @data: Private data pointer from eap_sim_db_init()
* @reauth: Pointer to re-authentication entry from
* eap_sim_db_get_reauth_entry()
*/
-void eap_sim_db_remove_reauth(void *priv, struct eap_sim_reauth *reauth)
+void eap_sim_db_remove_reauth(struct eap_sim_db_data *data,
+ struct eap_sim_reauth *reauth)
{
- struct eap_sim_db_data *data = priv;
struct eap_sim_reauth *r, *prev = NULL;
#ifdef CONFIG_SQLITE
if (data->sqlite_db) {
/**
* eap_sim_db_get_aka_auth - Get AKA authentication values
- * @priv: Private data pointer from eap_sim_db_init()
+ * @data: Private data pointer from eap_sim_db_init()
* @username: Permanent username (prefix | IMSI)
* @_rand: Buffer for RAND value
* @autn: Buffer for AUTN value
* eap_sim_db_get_aka_auth() function will then be called again and the newly
* received triplets will then be given to the caller.
*/
-int eap_sim_db_get_aka_auth(void *priv, const char *username, u8 *_rand,
- u8 *autn, u8 *ik, u8 *ck, u8 *res, size_t *res_len,
- void *cb_session_ctx)
+int eap_sim_db_get_aka_auth(struct eap_sim_db_data *data, const char *username,
+ u8 *_rand, u8 *autn, u8 *ik, u8 *ck,
+ u8 *res, size_t *res_len, void *cb_session_ctx)
{
- struct eap_sim_db_data *data = priv;
struct eap_sim_db_pending *entry;
int len;
char msg[40];
if (entry == NULL)
return EAP_SIM_DB_FAILURE;
- os_get_time(&entry->timestamp);
entry->aka = 1;
os_strlcpy(entry->imsi, imsi, sizeof(entry->imsi));
entry->cb_session_ctx = cb_session_ctx;
/**
* eap_sim_db_resynchronize - Resynchronize AKA AUTN
- * @priv: Private data pointer from eap_sim_db_init()
+ * @data: Private data pointer from eap_sim_db_init()
* @username: Permanent username
* @auts: AUTS value from the peer
* @_rand: RAND value used in the rejected message
* eap_sim_db_get_aka_auth() will be called again to to fetch updated
* RAND/AUTN values for the next challenge.
*/
-int eap_sim_db_resynchronize(void *priv, const char *username,
+int eap_sim_db_resynchronize(struct eap_sim_db_data *data,
+ const char *username,
const u8 *auts, const u8 *_rand)
{
- struct eap_sim_db_data *data = priv;
const char *imsi;
size_t imsi_len;
len += imsi_len;
ret = os_snprintf(msg + len, sizeof(msg) - len, " ");
- if (ret < 0 || (size_t) ret >= sizeof(msg) - len)
+ if (os_snprintf_error(sizeof(msg) - len, ret))
return -1;
len += ret;
len += wpa_snprintf_hex(msg + len, sizeof(msg) - len,
auts, EAP_AKA_AUTS_LEN);
ret = os_snprintf(msg + len, sizeof(msg) - len, " ");
- if (ret < 0 || (size_t) ret >= sizeof(msg) - len)
+ if (os_snprintf_error(sizeof(msg) - len, ret))
return -1;
len += ret;
len += wpa_snprintf_hex(msg + len, sizeof(msg) - len,
*/
char * sim_get_username(const u8 *identity, size_t identity_len)
{
- char *username;
size_t pos;
+ if (identity == NULL)
+ return NULL;
+
for (pos = 0; pos < identity_len; pos++) {
if (identity[pos] == '@' || identity[pos] == '\0')
break;
}
- username = os_malloc(pos + 1);
- if (username == NULL)
- return NULL;
- os_memcpy(username, identity, pos);
- username[pos] = '\0';
-
- return username;
+ return dup_binstr(identity, pos);
}