added session manager and support for an external login system
[TransparentIRC.git] / src / UserClient.c
index fccf56b1b563bff933b8ecc875a254df53302096..e64b8a0befd995b3e40f40df74629022ff9e83d9 100644 (file)
@@ -17,6 +17,8 @@
 #include "UserClient.h"
 #include "IOHandler.h"
 #include "ServerSocket.h"
+#include "UserSession.h"
+#include "tools.h"
 
 static void userclient_callback(struct IOEvent *event);
 
@@ -29,12 +31,17 @@ void userclient_accepted(struct ServerSocket *server, int sockfd) {
     iofd->state = IO_CONNECTED;
     iofd->read_lines = 1;
     iohandler_update(iofd);
-    client = malloc(sizeof(*client));
+    client = calloc(1, sizeof(*client));
     client->iofd = iofd;
     iofd->data = client;
     client->server = server;
     server->clientcount++;
     
+    struct UserLogin *login = calloc(1, sizeof(*login));
+    client->user = login;
+    login->client = client;
+    
+    
     //add UserClient to the list
     client->prev = NULL;
     client->next = userclients;
@@ -43,10 +50,29 @@ void userclient_accepted(struct ServerSocket *server, int sockfd) {
     userclients = client;
     
     //let's say hello to the client
-    iohandler_printf(iofd, "NOTICE AUTH :*** TransparentIRC " TRANSIRC_VERSION " (use /quote transirc for more information)");
+    iohandler_printf(iofd, "NOTICE AUTH :*** [TransparentIRC] TransparentIRC v" TRANSIRC_VERSION " (use /quote transirc for more information)");
 }
 
 void userclient_close(struct UserClient *client) {
+    if(client->flags & USERCLIENT_LOGGED_IN) {
+        usersession_client_close(client->user);
+    } else {
+        struct UserLogin *login = client->user;
+        if(client->flags & USERCLIENT_LOGIN_PROCESSING) {
+            usersession_login_abort(login);
+        }
+        if(login->username)
+            free(login->username);
+        if(login->password)
+            free(login->password);
+        if(login->nick)
+            free(login->nick);
+        if(login->reject_reason)
+            free(login->reject_reason);
+        if(login->session_class)
+            free(login->session_class);
+        free(login);
+    }
     iohandler_close(client->iofd);
     client->server->clientcount--;
     if(client->prev)
@@ -55,6 +81,7 @@ void userclient_close(struct UserClient *client) {
         userclients = client->next;
     if(client->next)
         client->next->prev = client->prev;
+    
     free(client);
 }
 
@@ -72,7 +99,72 @@ void userclient_close_server(struct ServerSocket *server, int keep_clients) {
 }
 
 static void userclient_recv(struct UserClient *client, char *line) {
-    iohandler_printf(client->iofd, "reply: %s", line);
+    if(!stricmplen(line, "TRANSIRC ", 9)) {
+        /*
+        char *argv[MAXNUMPARAMS];
+        int argc = parse_line(line, argv, 1);
+        */
+        
+    } else if(!(client->flags & USERCLIENT_LOGGED_IN)) {
+        struct UserLogin *login = client->user;
+        char *argv[MAXNUMPARAMS];
+        int argc = parse_line(line, argv, 1);
+        if(argc < 3) return;
+        if(!stricmp(argv[1], "PASS")) {
+            char *delimiter = strchr(argv[2], ':');
+            if(login->password)
+                free(login->password);
+            if(delimiter) {
+                *delimiter = '\0';
+                delimiter++;
+                if(login->username)
+                    free(login->username);
+                login->username = strdup(argv[2]);
+                login->password = strdup(delimiter);
+            } else 
+                login->password = strdup(argv[2]);
+        } else if(!stricmp(argv[1], "USER")) {
+            if(!login->username)
+                login->username = strdup(argv[2]);
+        } else if(!stricmp(argv[1], "NICK")) {
+            if(login->nick)
+                free(login->nick);
+            login->nick = strdup(argv[2]);
+            if(!login->password) {
+                iohandler_printf(client->iofd, "NOTICE AUTH :*** [TransparentIRC] You need to send your LOC data. Try /quote PASS <username>:<password>");
+            }
+        }
+        if(login->username && login->password && login->nick && !(client->flags & USERCLIENT_LOGIN_PROCESSING)) {
+            //try to login
+            iohandler_printf(client->iofd, "NOTICE AUTH :*** [TransparentIRC] Checking login...");
+            usersession_login(login);
+        }
+    } else {
+        
+    }
+}
+
+void userclient_login_failed(struct UserLogin *login, char *reason) {
+    iohandler_printf(login->client->iofd, "NOTICE AUTH :*** [TransparentIRC] Login rejected");
+    userclient_close(login->client);
+}
+
+void userclient_login_successful(struct UserLogin *login, struct UserSession *session, int recover) {
+    struct UserClient *client = login->client;
+    iohandler_printf(client->iofd, "NOTICE AUTH :*** [TransparentIRC] Login accepted.");
+    if(login->username)
+        free(login->username);
+    if(login->password)
+        free(login->password);
+    if(login->nick)
+        free(login->nick);
+    free(login);
+    client->user = session;
+    if(recover) {
+        iohandler_printf(client->iofd, "NOTICE AUTH :*** [TransparentIRC] Recovering previous link (Nick: %s).", session->nick);
+        
+        
+    }
 }
 
 static void userclient_callback(struct IOEvent *event) {