Beispiel #1
0
Eina_Bool
email_pop3_stat_read(Email *e, const unsigned char *recv, size_t size)
{
   Email_Stat_Cb cb;
   int num;
   size_t len;

   cb = eina_list_data_get(e->cbs);
   if ((!email_op_ok((const unsigned char *)recv, size)) ||
       (sscanf((char*)recv, "+OK %u %zu", &num, &len) != 2))
     {
        ERR("Error with STAT");
        if (cb) cb(e, 0, 0);
        return EINA_TRUE;
     }
   INF("STAT returned %u messages (%zu octets)", num, len);
   if (cb) cb(e, num, len);
   return EINA_TRUE;
}
Beispiel #2
0
Eina_Bool
email_pop3_list_read(Email *e, Ecore_Con_Event_Server_Data *ev)
{
   Email_List_Cb cb;
   Eina_List *list = NULL;
   Email_List_Item *it;
   const char *p, *n;
   const unsigned char *data;
   size_t size;

   if ((!e->buf) && (!email_op_ok(ev->data, ev->size)))
     {
        ERR("Error with LIST");
        cb = eina_list_data_get(e->cbs);
        if (cb) cb(e, NULL);
        return EINA_TRUE;
     }
   if (e->buf)
     {
        eina_binbuf_append_length(e->buf, ev->data, ev->size);
        data = eina_binbuf_string_get(e->buf);
        size = eina_binbuf_length_get(e->buf);
     }
   else
     {
        data = ev->data;
        size = ev->size;
     }
   for (n = (char*)memchr(data + 3, '\n', size - 3), size -= (n - (char*)data);
        n && (size > 1);
        p = n, n = (char*)memchr(n, '\n', size - 1), size -= (n - (char*)data))
      {
         it = calloc(1, sizeof(Email_List_Item));
         if (sscanf(++n, "%u %zu", &it->id, &it->size) != 2)
           {
              free(it);
              break;
           }
         INF("Message %u: %zu octets", it->id, it->size);
         list = eina_list_append(list, it);
      }
   if (n[0] == '.')
     {
        cb = eina_list_data_get(e->cbs);
        INF("LIST returned %u messages", eina_list_count(list));
        if (cb) cb(e, list);
        EINA_LIST_FREE(list, it)
          free(it);
        if (e->buf)
          {
             eina_binbuf_free(e->buf);
             e->buf = NULL;
          }
     }
   else if (!e->buf)
     {
        e->buf = eina_binbuf_new();
        eina_binbuf_append_length(e->buf, (const unsigned char*)(n), size - (n - (char*)data));
     }
   return EINA_TRUE;
}
Beispiel #3
0
Eina_Bool
email_pop3_list_read(Email *e, Ecore_Con_Event_Server_Data *ev)
{
   Email_List_Cb cb;
   Eina_List *next, *list = NULL;
   Email_List_Item *it;
   const char *n;
   unsigned char *data;
   int len;
   size_t size;

   if ((!e->buf) && (!email_op_ok(ev->data, ev->size)))
     {
        ERR("Error with LIST");
        cb = e->cbs->data;
        e->cbs = eina_list_remove_list(e->cbs, e->cbs);
        if (cb) cb(e, NULL);
        return EINA_TRUE;
     }
   next = e->ev ? e->ev : list;
   if (e->buf)
     {
        eina_binbuf_append_length(e->buf, ev->data, ev->size);
        data = (unsigned char*)eina_binbuf_string_get(e->buf);
        len = eina_binbuf_length_get(e->buf);
     }
   else
     {
        data = ev->data;
        len = ev->size;
     }
   for (n = (char*)memchr(data + 3, '\n', len - 3), size = len - (n - (char*)data);
        n && (size > 1);
        n = (char*)memchr(n, '\n', size - 1), size = len - (n - (char*)data))
      {
         it = calloc(1, sizeof(Email_List_Item));
         if (sscanf(++n, "%u %zu", &it->id, &it->size) != 2)
           {
              free(it);
              break;
           }
         INF("Message %u: %zu octets", it->id, it->size);
         list = eina_list_append(list, it);
      }
   if (!memcmp(n - 2, "\r\n.\r\n", 5))
     {
        cb = e->cbs->data;
        e->cbs = eina_list_remove_list(e->cbs, e->cbs);
        INF("LIST returned %u messages", eina_list_count(list));
        if (cb) cb(e, list);
        EINA_LIST_FREE(list, it)
          free(it);
        if (e->buf)
          {
             eina_binbuf_free(e->buf);
             e->buf = NULL;
          }
        return EINA_TRUE;
     }
   else if (!e->buf)
     {
        e->buf = eina_binbuf_new();
        eina_binbuf_append_length(e->buf, (unsigned char*)n, ev->size - (n - (char*)ev->data));
     }
   return EINA_FALSE;
}
Beispiel #4
0
void
email_login_pop(Email *e, Ecore_Con_Event_Server_Data *ev)
{
    char *buf;
    size_t size;

    switch (e->state)
    {
    case EMAIL_STATE_SSL:
        if (!email_op_ok(ev->data, ev->size))
        {
            ERR("Could not create secure connection!");
            ecore_con_server_del(ev->server);
            return;
        }
        ecore_con_ssl_server_upgrade(e->svr, ECORE_CON_USE_MIXED);
        ecore_con_ssl_server_verify_basic(e->svr);
        e->flags = ECORE_CON_USE_MIXED;
        return;
    case EMAIL_STATE_INIT:
        if (!email_op_ok(ev->data, ev->size))
        {
            ERR("Not a POP3 server!");
            ecore_con_server_del(ev->server);
            return;
        }
        if (ev->size > 20)
        {
            const unsigned char *end;

            end = memrchr(ev->data + 3, '>', ev->size - 3);
            if (end)
            {
                const unsigned char *start;

                start = memrchr(ev->data + 3, '<', end - (unsigned char*)ev->data);
                if (start)
                {
                    e->features.pop_features.apop = EINA_TRUE;
                    e->features.pop_features.apop_str = eina_binbuf_new();
                    eina_binbuf_append_length(e->features.pop_features.apop_str, start, end - start + 1);
                }
            }
        }
        if (e->secure && (!e->flags))
        {
            email_write(e, "STLS\r\n", sizeof("STLS\r\n") - 1);
            e->state++;
            return;
        }
        e->state = EMAIL_STATE_USER;
        ev = NULL;
    case EMAIL_STATE_USER:
        if (!ev)
        {
            unsigned char digest[16];
            char md5buf[33];

            if (!e->features.pop_features.apop)
            {
                INF("Beginning AUTH PLAIN");
                size = sizeof(char) * (sizeof("USER ") - 1 + sizeof("\r\n") - 1 + strlen(e->username)) + 1;
                buf = alloca(size);
                snprintf(buf, size, "USER %s\r\n", e->username);
                email_write(e, buf, size - 1);
                return;
            }
            INF("Beginning AUTH APOP");
            e->state++;
            eina_binbuf_append_length(e->features.pop_features.apop_str, (unsigned char*)e->password, strlen(e->password));

            md5_buffer((char*)eina_binbuf_string_get(e->features.pop_features.apop_str), eina_binbuf_length_get(e->features.pop_features.apop_str), digest);
            email_md5_digest_to_str(digest, md5buf);
            size = sizeof(char) * (sizeof("APOP ") - 1 + sizeof("\r\n") - 1 + strlen(e->username)) + sizeof(md5buf);
            buf = alloca(size);
            snprintf(buf, size, "APOP %s %s\r\n", e->username, md5buf);
            email_write(e, buf, size - 1);
            return;
        }
        if (!email_op_ok(ev->data, ev->size))
        {
            ERR("Username invalid!");
            ecore_con_server_del(e->svr);
            return;
        }
        size = sizeof(char) * (sizeof("PASS ") - 1 + sizeof("\r\n") - 1 + strlen(e->password)) + 1;
        buf = alloca(size);
        snprintf(buf, size, "PASS %s\r\n", e->password);
        DBG("Sending password");
        ecore_con_server_send(e->svr, buf, size - 1);
        e->state++;
        return;
    case EMAIL_STATE_PASS:
        if (!email_op_ok(ev->data, ev->size))
        {
            ERR("Credentials invalid!");
            ecore_con_server_del(e->svr);
            return;
        }
        INF("Logged in successfully!");
        e->state++;
        ecore_event_add(EMAIL_EVENT_CONNECTED, e, (Ecore_End_Cb)email_fake_free, NULL);
    default:
        break;
    }
}
Beispiel #5
0
Eina_Bool
data_pop(Email *e, int type __UNUSED__, Ecore_Con_Event_Server_Data *ev)
{
   char *recv;

   if (e != ecore_con_server_data_get(ev->server))
     {
        DBG("Event mismatch");
        return ECORE_CALLBACK_PASS_ON;
     }

   recv = alloca(ev->size + 1);
   memcpy(recv, ev->data, ev->size);
   recv[ev->size] = 0;
   DBG("Receiving %i bytes:\n%s", ev->size, recv);

   if (e->state < EMAIL_STATE_CONNECTED)
     {
        email_login_pop(e, ev);
        return ECORE_CALLBACK_RENEW;
     }

   if (!e->current) return ECORE_CALLBACK_RENEW;

   switch (e->current)
     {
      case EMAIL_OP_STAT:
        if (!email_pop3_stat_read(e, recv, ev->size)) return ECORE_CALLBACK_RENEW;
        break;
      case EMAIL_OP_LIST:
        if (!email_pop3_list_read(e, ev)) return ECORE_CALLBACK_RENEW;
        break;
      case EMAIL_OP_RETR:
        if (!email_pop3_retr_read(e, ev)) return ECORE_CALLBACK_RENEW;
        break;
      case EMAIL_OP_DELE:
      case EMAIL_OP_QUIT:
      {
         Ecore_Cb cb;

         cb = e->cbs->data;
         e->cbs = eina_list_remove_list(e->cbs, e->cbs);
         if (!email_op_ok(ev->data, ev->size))
           {
              if (e->current == EMAIL_OP_DELE) ERR("Error with DELE");
              else ERR("Error with QUIT");
           }
         else
           {
              if (e->current == EMAIL_OP_DELE) INF("DELE successful");
              else INF("QUIT");
           }
         if (cb) cb(e);
         if (e->current == EMAIL_OP_QUIT) ecore_con_server_del(e->svr);
         break;
      }
      default:
        break;
     }
   next_pop(e);
   return ECORE_CALLBACK_RENEW;
}