Implement server port support and update copyright year and style.
[cascardo/rnetproxy.git] / pop.c
diff --git a/pop.c b/pop.c
index 6c33235..0477815 100644 (file)
--- a/pop.c
+++ b/pop.c
 **  
 */
 
-#include <gnet.h>
 #include <glib.h>
 #include <string.h>
 #include "nethook.h"
 #include "pop.h"
+#include "usermap.h"
 
 typedef struct
 {
@@ -30,8 +30,36 @@ typedef struct
   gpointer orig_data;
   GString *buffer;
   GString *line;
+  gchar *user;
 } pop_t;
 
+static int
+pop_check_user (pop_t *pop)
+{
+  gchar *end;
+  gchar *s;
+  end = pop->line->str + pop->line->len;
+  s = pop->line->str;
+  while (s < end && *s == ' ') s++;
+  if (end - s < 5)
+    return -1;
+  if (g_ascii_strncasecmp (s, "USER ", 5) != 0)
+    return -1;
+  s += 5;
+  while (s < end && *s == ' ') s++;
+  if (s == end)
+    return -1;
+  end--;
+  while (end >= s && (*end == '\n' || *end == '\r')) end--;
+  if (end < s)
+    return -1;
+  if (pop->user)
+    g_free (pop->user);
+  pop->user = g_strndup (s, end - s + 2);
+  pop->user[end - s + 1] = 0;
+  return 0;
+}
+
 static int
 pop_getline (pop_t *pop)
 {
@@ -54,10 +82,23 @@ pop_read (net_hook_t *hook, gchar *buffer, size_t len)
 {
   pop_t *pop = hook->data;
   g_string_append_len (pop->buffer, buffer, len);
-  hook->data = pop->orig_data;
   while (pop_getline (pop) == 0)
-    pop->orig_read (hook, pop->line->str, pop->line->len);
-  hook->data = pop;
+    {
+      if (pop_check_user (pop) == 0)
+        {
+          g_message ("User is trying to authenticate as %s.", pop->user);
+          if (usermap_perm (pop->user) == ACCESS_DENY)
+            {
+              g_message ("Denying access to user %s.", pop->user);
+              pop_destroy (hook);
+              hc_conn_close (hook->conn);
+              return;
+            }
+        }
+      hook->data = pop->orig_data;
+      pop->orig_read (hook, pop->line->str, pop->line->len);
+      hook->data = pop;
+    }
 }
 
 net_hook_t *
@@ -69,6 +110,7 @@ pop_hook_new (net_hook_t *layer)
   pop->orig_data = layer->data;
   pop->buffer = g_string_sized_new (4096);
   pop->line = g_string_sized_new (4096);
+  pop->user = NULL;
   layer->read = pop_read;
   layer->data = pop;
   return layer;
@@ -80,6 +122,8 @@ pop_destroy (net_hook_t *hook)
   pop_t *pop = hook->data;
   g_string_free (pop->buffer, TRUE);
   g_string_free (pop->line, TRUE);
+  if (pop->user)
+    g_free (pop->user);
   hook->read = pop->orig_read;
   hook->data = pop->orig_data;
   g_slice_free (net_hook_t, (gpointer) pop);