Check os_snprintf() result more consistently - automatic 1
[mech_eap.git] / src / eap_server / eap_sim_db.c
index 474b172..3b689ed 100644 (file)
@@ -38,7 +38,6 @@ struct eap_sim_db_pending {
        char imsi[20];
        enum { PENDING, SUCCESS, FAILURE } state;
        void *cb_session_ctx;
-       struct os_time timestamp;
        int aka;
        union {
                struct {
@@ -216,26 +215,23 @@ static int get_pseudonym_cb(void *ctx, int argc, char *argv[], char *col[])
 }
 
 
-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;
 }
 
 
@@ -577,16 +573,14 @@ static void eap_sim_db_receive(int sock, void *eloop_ctx, void *sock_ctx)
        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 "
@@ -633,7 +627,7 @@ static int eap_sim_db_open_socket(struct eap_sim_db_data *data)
 
        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;
        }
 
@@ -643,8 +637,13 @@ static int eap_sim_db_open_socket(struct eap_sim_db_data *data)
                    "/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;
@@ -654,12 +653,16 @@ static int eap_sim_db_open_socket(struct eap_sim_db_data *data)
        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;
        }
 
@@ -691,9 +694,10 @@ static void eap_sim_db_close_socket(struct eap_sim_db_data *data)
  * @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;
@@ -806,7 +810,8 @@ static int eap_sim_db_send(struct eap_sim_db_data *data, const char *msg,
 
        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 ||
@@ -818,7 +823,8 @@ static int eap_sim_db_send(struct eap_sim_db_data *data, const char *msg,
                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;
                }
        }
@@ -837,7 +843,7 @@ static void eap_sim_db_expire_pending(struct eap_sim_db_data *data)
 
 /**
  * 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
@@ -858,11 +864,11 @@ static void eap_sim_db_expire_pending(struct eap_sim_db_data *data)
  * 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];
@@ -921,7 +927,7 @@ int eap_sim_db_get_gsm_triplets(void *priv, const char *username, int max_chal,
        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;
 
@@ -934,7 +940,6 @@ int eap_sim_db_get_gsm_triplets(void *priv, const char *username, int max_chal,
        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;
@@ -945,58 +950,6 @@ int eap_sim_db_get_gsm_triplets(void *priv, const char *username, int max_chal,
 }
 
 
-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;
@@ -1011,7 +964,7 @@ static char * eap_sim_db_get_next(struct eap_sim_db_data *data, char prefix)
        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;
 }
@@ -1019,7 +972,7 @@ static char * eap_sim_db_get_next(struct eap_sim_db_data *data, char prefix)
 
 /**
  * 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
  *
@@ -1028,9 +981,9 @@ static char * eap_sim_db_get_next(struct eap_sim_db_data *data, char prefix)
  * 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) {
@@ -1051,7 +1004,7 @@ char * eap_sim_db_get_next_pseudonym(void *priv, enum eap_sim_db_method 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
  *
@@ -1061,9 +1014,9 @@ char * eap_sim_db_get_next_pseudonym(void *priv, enum eap_sim_db_method method)
  * 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) {
@@ -1084,7 +1037,7 @@ char * eap_sim_db_get_next_reauth_id(void *priv, enum eap_sim_db_method 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
@@ -1094,10 +1047,9 @@ char * eap_sim_db_get_next_reauth_id(void *priv, enum eap_sim_db_method method)
  * 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);
@@ -1198,12 +1150,14 @@ eap_sim_db_add_reauth_data(struct eap_sim_db_data *data,
  * 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,
@@ -1222,7 +1176,7 @@ int eap_sim_db_add_reauth(void *priv, const char *permanent, char *reauth_id,
 #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
@@ -1237,11 +1191,11 @@ int eap_sim_db_add_reauth(void *priv, const char *permanent, char *reauth_id,
  * 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 "
@@ -1267,54 +1221,68 @@ int eap_sim_db_add_reauth_prime(void *priv, const char *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) {
@@ -1340,7 +1308,7 @@ void eap_sim_db_remove_reauth(void *priv, struct eap_sim_reauth *reauth)
 
 /**
  * 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
@@ -1362,11 +1330,10 @@ void eap_sim_db_remove_reauth(void *priv, struct eap_sim_reauth *reauth)
  * 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];
@@ -1432,7 +1399,6 @@ int eap_sim_db_get_aka_auth(void *priv, const char *username, u8 *_rand,
        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;
@@ -1446,7 +1412,7 @@ int eap_sim_db_get_aka_auth(void *priv, const char *username, u8 *_rand,
 
 /**
  * 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
@@ -1458,10 +1424,10 @@ int eap_sim_db_get_aka_auth(void *priv, const char *username, u8 *_rand,
  * 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;
 
@@ -1489,13 +1455,13 @@ int eap_sim_db_resynchronize(void *priv, const char *username,
                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,
@@ -1520,19 +1486,15 @@ int eap_sim_db_resynchronize(void *priv, const char *username,
  */
 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);
 }