void Dispatcher::run() { while(1) { TCPSocket* speaker = multiListener->listenToSocket(10); if(speaker!=NULL) { int cmd; speaker->recv((char*)&cmd,4); cmd = ntohl(cmd); switch(cmd) { case SESSION_ESTABLISHED: cout<<"connected"; break; case OPEN_SESSION_WITH_PEER: {string dest = ReceiveMsg(speaker); ConnectRequest(speaker->destIpAndPort(),dest);} break; case USER_LIST: sendUserList(speaker); break; case ROOM_LIST: sendRoomList(speaker); break; case MEMBERS_LIST: {string room = ReceiveMsg(speaker); sendMembersList(speaker,room);} break; case CREATE_CHAT: SetActiveChat(speaker->destIpAndPort()); break; case CLOSE_CHAT: CloseUserChat(speaker->destIpAndPort()); break; case CLOSE_SESSION_WITH_PEER: closePeer(speaker->destIpAndPort()); break; default: break; } } } }
/** * Autentificación con contraseña */ void authPassword(user* conn, int* connTam, int socketID, sms msj, sqlite3* db, room* rooms, int dim){ sms auxMsj; int rol = 0; PDEBUG("DATA: Autentificando con contraseña\n"); PDEBUG("INFO: ¿Usuario Registrado?\n"); /** para evitar posibles ataques vamos a comprobar que el nombre del usuario * asociado a este socket existe */ int aux = searchConn(conn, *connTam, socketID); PDEBUG("INFO: Comprobando usuario\n"); if(strcmp((*(conn + aux)).name, "") != 0){ PDEBUG("INFO: Comprobando contraseña\n"); if((rol = db_checkUser((*(conn + aux)).name, msj.text, &db)) <= 0){ PDEBUG("INFO: Usuario o/y contraseña incorrectos\n");// intento de conexión fraudulento strcpy((*(conn + aux)).name, ""); auxMsj.flag = REQ_TEXT; strcpy(auxMsj.name, SERVER); strcpy(auxMsj.text, "Usuario o/y contraseña incorrectos, Inserte un usuario"); SSL_write((*(conn + aux)).ssl, &auxMsj, sizeof(sms)); }else{// conexión correcta (*(conn + aux)).prov = FINAL; (*(conn + aux)).rol = rol; PDEBUG("INFO: Enviando mensaje de bienvenida\n"); auxMsj.flag = MSJ; strcpy(auxMsj.name, SERVER); strcpy(auxMsj.text, "Conexión realizada\n"); SSL_write((*(conn + aux)).ssl, &auxMsj, sizeof(sms)); // hacemos el broadcast para avisar de la existencia de un nuevo usuario PDEBUG("INFO: Solicitando el ingreso en una sala\n"); strcpy(auxMsj.text, "Salas de chat..."); SSL_write((*(conn + aux)).ssl, &auxMsj, sizeof(sms)); sendRoomList((*(conn + aux)).ssl, rooms, dim); PDEBUG("INFO: Pidiendo la sala\n"); auxMsj.flag = REQ_ROOM; strcpy(auxMsj.text, "Seleccione la sala:"); SSL_write((*(conn + aux)).ssl, &auxMsj, sizeof(sms)); } }else{ // intento de conexión fraudulento PDEBUG("INFO: INTENTO DE CONEXÓN FRAUDULENTO\n"); auxMsj.flag = MSJ; strcpy(auxMsj.name, SERVER); strcpy(auxMsj.text, "INTENTO DE CONEXIÓN FRAUDULENTO"); SSL_write((*(conn + aux)).ssl, &auxMsj, sizeof(sms)); } }
void roomCheckIn(user* conn, int* connTam, int socketID, sms msj, sqlite3* db, room* rooms, int dim){ int room = 0; sms auxMsj; PDEBUG("INFO: Buscando la sala\n"); room = searchRoom(msj.text, rooms, dim); int aux = searchConn(conn, *connTam, socketID); auxMsj.flag = MSJ; strcpy(auxMsj.name, SERVER); if(room < 0){ // sala no encontrada PDEBUG("INFO: Solicitando el ingreso en una sala\n"); strcpy(auxMsj.text, "Sala inválida, Salas de chat..."); SSL_write((*(conn + aux)).ssl, &auxMsj, sizeof(sms)); sendRoomList((*(conn + aux)).ssl, rooms, dim); PDEBUG("INFO: Pidiendo la sala\n"); auxMsj.flag = REQ_ROOM; strcpy(auxMsj.text, "Seleccione la sala:"); SSL_write((*(conn + aux)).ssl, &auxMsj, sizeof(sms)); }else{ // sala encontrada PDEBUG("INFO: Asignando sala y enviando mensaje de confirmación\n"); (*(conn + aux)).room = room; auxMsj.flag = OK; strcpy(auxMsj.text, "Conectado correctamente a la sala..."); SSL_write((*(conn + aux)).ssl, &auxMsj, sizeof(sms)); PDEBUG("INFO: Haciendo Multicast de la nueva conexión\n"); sprintf(auxMsj.text, "Usuario '%s' Conectado \n", (*(conn + aux)).name); multicast(conn, connTam, auxMsj, socketID, db, room); return; } }
/** * Autentificación */ void auth(user* conn, int* connTam, int socketID, sms msj, sqlite3* db, room* rooms, int dim){ sms auxMsj; char auxc[DIM]; int guest = 0; PDEBUG("DATA: Autentificando\n"); PDEBUG("INFO: ¿Usuario Registrado?\n"); int aux = searchConn(conn, *connTam, socketID); if(db_userExists(msj.text, &db) <= 0){ // el usuario no es un usuario registrado PDEBUG("INFO: No es un usuario registrado\n"); //dado que no es un usuario registrado, lo conectamos como invitado strcpy(auxc, msj.text); strcat(auxc, "-guest"); guest = 1; }else{ PDEBUG("INFO: Sí es un usuario registrado\n"); /** dado que sí es un usuario registrado, le pedimos que se autentifique * con el password por lo que lo indicamos con un flag */ strcpy(auxc, msj.text); guest = 0; } PDEBUG("INFO: ¿Nombre de usuario en uso?\n"); if(checkName(conn, *connTam, auxc) != 0){ PDEBUG("INFO: Usuario no conectado\n");// alamcenando el nombre del usuario strcpy((*(conn + aux)).name, auxc); if(guest == 1){ // el usuario no está conectado y no requiere autentificación por contraseña // nombre de usuario libre para su uso, asignandolo... PDEBUG("INFO: Usuario conectado, almacenando la conexión\n"); // metemos los datos de la conexión en nuestro array de conexiones (*(conn + aux)).prov = FINAL; (*(conn + aux)).rol = GUEST; PDEBUG("INFO: Enviando mensaje de bienvenida\n"); auxMsj.flag = MSJ; strcpy(auxMsj.name, SERVER); strcpy(auxMsj.text, "Conexión realizada\n"); SSL_write((*(conn + aux)).ssl, &auxMsj, sizeof(sms)); // hacemos el broadcast para avisar de la existencia de un nuevo usuario PDEBUG("INFO: Solicitando el ingreso en una sala\n"); strcpy(auxMsj.text, "Salas de chat..."); SSL_write((*(conn + aux)).ssl, &auxMsj, sizeof(sms)); sendRoomList((*(conn + aux)).ssl, rooms, dim); PDEBUG("INFO: Pidiendo la sala\n"); auxMsj.flag = REQ_ROOM; strcpy(auxMsj.text, "Seleccione la sala:"); SSL_write((*(conn + aux)).ssl, &auxMsj, sizeof(sms)); }else{ // el usuario es un usuario registrado y requiere contraseña PDEBUG("INFO: solicitando password\n"); // metemos los datos de la conexión en nuestro array de conexiones strcpy((*(conn + aux)).name, msj.text); // guardamos el nombre del usuario para luego autenticar auxMsj.flag = REQ_PASS; strcpy(auxMsj.name, SERVER); strcpy(auxMsj.text, "Password: "******"INFO: Usuario existente\n"); auxMsj.flag = REQ_TEXT; // le indicamos que requerimos una respuesta con texto strcpy(auxMsj.name, SERVER); // nos identificamos como el servidor strcpy(auxMsj.text, "Usuario Existente.\nUsuario: "); // establecemos el texto que queremos que se muestre SSL_write((*(conn + aux)).ssl, &auxMsj, sizeof(sms)); } }
/** * Ejecuta en el servidor la cadena recibida */ int execParams(user* conn, int connTam, char* str, int socketID, int sock, sqlite3* db, room* rooms, int dim){ PDEBUG("INFO: Analizando lista de parámetros\n"); char saux[10][DIM]; bzero(saux, 10 * DIM); int error = 0; // tienes permisos para ejecutar comandos en el servidor??? PDEBUG("INFO: Comprobando permisos\n"); int aux = searchConn(conn, connTam, socketID); // almacenamos en la base de datos sms auxMsj; strcpy(auxMsj.name, (*(conn + aux)).name); strcpy(auxMsj.text, str); db_addLog(auxMsj, &db); if((*(conn + aux)).rol != ADMIN){ PDEBUG("INFO: Usuario sin permisos\n"); sms auxMsj; auxMsj.flag = MSJ; strcpy(auxMsj.name, SERVER); strcpy(auxMsj.text, "Usuario sin permisos"); SSL_write((*(conn + aux)).ssl, &auxMsj, sizeof(sms)); PDEBUG("INFO: Mensaje de usuario no válido enviado al emisor\n"); return -1; } PDEBUG("INFO: Usuario autorizado\n"); str = trim(str); // eliminamos os espacios en blanco if(strcmp(str, "-x") == 0){ // comando de salida PDEBUG("EXIT: Cerrando el servidor\n"); shutdown(sock, SHUT_RDWR); // cerramos el socket sms auxMsj; auxMsj.flag = SERV_EXIT; strcpy(auxMsj.name, SERVER); broadcast(conn, &connTam, auxMsj, socketID, db); closeAll(conn, &connTam); // cerramos todas las conexiones PDEBUG("EXIT: Cerrando la conexión con la base de datos\n"); db_close(&db); PDEBUG("EXIT: Liberando espacio\n"); free(conn); PDEBUG("EXIT: Cerrando el proceso\n"); exit(0); }else if(sscanf(str, "--add-user %s %s %s", saux[0], saux[1], saux[2]) == 3){ // añadiendo un usuario //saux[0] es el nombre //saux[1] es el password //saux[2] es el rol PDEBUG("INFO: Añadiendo usuario 3 param\n"); int rol = 0; if(strcmp(saux[2], "admin") == 0){ rol = ADMIN; }else if(strcmp(saux[2], "user") == 0){ rol = USER; }else{ PDEBUG("INFO: tercer argumento no válido"); sms auxMsj; auxMsj.flag = MSJ; strcpy(auxMsj.name, SERVER); strcpy(auxMsj.text, "Rol no reconocido."); SSL_write((*(conn + aux)).ssl, &auxMsj, sizeof(sms)); return 0; } error = db_addUser(saux[0], saux[1], rol, &db); sms auxMsj; auxMsj.flag = MSJ; strcpy(auxMsj.name, SERVER); if(error == 0){ strcpy(auxMsj.text, "Usuario creado"); }else if(error == 1){ strcpy(auxMsj.text, "Nombre de usuario en uso"); }else{ strcpy(auxMsj.text, "Error al crear el usuario"); } SSL_write((*(conn + aux)).ssl, &auxMsj, sizeof(sms)); }else if(sscanf(str, "--add-user %s %s", saux[0], saux[1]) == 2){ // añadiendo un usuario // se usará el rol por defecto //saux[0] es el nombre //saux[1] es el password PDEBUG("INFO: Añadiendo usuario 2 param\n"); error = db_addUser(saux[0], saux[1], USER, &db); sms auxMsj; auxMsj.flag = MSJ; strcpy(auxMsj.name, SERVER); if(error == 0){ strcpy(auxMsj.text, "Usuario creado"); }else if(error == 1){ strcpy(auxMsj.text, "Nombre de usuario en uso"); }else{ strcpy(auxMsj.text, "Error al crear el usuario"); } SSL_write((*(conn + aux)).ssl, &auxMsj, sizeof(sms)); }else if(sscanf(str, "--delete-user %s", saux[0]) == 1){ // borrando un usuario //saux[0] es el nombre PDEBUG("INFO: Borrando usuario\n"); int num = 0; num = db_deleteUser(saux[0], &db); sms auxMsj; auxMsj.flag = MSJ; strcpy(auxMsj.name, SERVER); if(num > 0){ PDEBUG("INFO: Usuario borrado\n"); strcpy(auxMsj.text, "Usuario borrado"); }else{ PDEBUG("INFO: Usuario no encontrado\n"); strcpy(auxMsj.text, "Usuario no encontrado"); } SSL_write((*(conn + aux)).ssl, &auxMsj, sizeof(sms)); }else if(strcmp(str, "--list-user") == 0){ // listando usuarios //saux[0] es el nombre PDEBUG("INFO: listando usuarios\n"); int num = 0; num = db_listUser(socketID, &db); }else if(sscanf(str, "--log %s %s", saux[0], saux[1]) == 2){ // listando usuarios //saux[0] es la fecha de inicio //saux[1] es la fecha de finalización PDEBUG("INFO: listando usuarios\n"); int num = 0; struct tm tm1, tm2; long t1, t2; if (strptime(saux[0], "%d/%m/%Y", &tm1) == 0 || strptime(saux[1], "%d/%m/%Y", &tm2) == 0){ PDEBUG("INFO: Formato de fecha no válido\n"); sms auxMsj; auxMsj.flag = MSJ; strcpy(auxMsj.name, SERVER); strcpy(auxMsj.text, "Formato de fecha no válido -> dd/mm/YYYY"); SSL_write((*(conn + aux)).ssl, &auxMsj, sizeof(sms)); return -1; } t1 = (long)mktime(&tm1); t2 = (long)mktime(&tm2); sprintf(saux[0], " WHERE time > %ld AND time < %ld", t1, t2); num = db_getLogPar(socketID, &db, saux[0]); }else if(strcmp(str, "--log") == 0){ // listando usuarios PDEBUG("INFO: listando usuarios\n"); int num = 0; num = db_getLog(socketID, &db); }else if(sscanf(str, "--add-room %s", saux[0]) == 1){ // creacion de un cana // saux[0] es el nombre del canal PDEBUG("INFO: añadiendo canales\n"); sms auxMsj; auxMsj.flag = MSJ; strcpy(auxMsj.name, SERVER); if(addRoom(saux[0], rooms, dim) == -1){ strcpy(auxMsj.text, "Error al crear el canal, mire el log para más información"); }else{ strcpy(auxMsj.text, "Canal creado"); } SSL_write((*(conn + aux)).ssl, &auxMsj, sizeof(sms)); }else if(sscanf(str, "--delete-room %s", saux[0]) == 1){ // creacion de un cana // saux[0] es el nombre del canal PDEBUG("INFO: borrando canal\n"); sms auxMsj; auxMsj.flag = MSJ; strcpy(auxMsj.name, SERVER); PDEBUG("INFO: Moviendo usuarios\n"); strcpy(saux[1], "general"); moveAllTo(conn, &connTam, saux[0], rooms, dim, db, saux[1]); if(deleteRoom(saux[0], rooms, dim) == -1){ strcpy(auxMsj.text, "Error al borrar el canal, mire el log para más información"); }else{ strcpy(auxMsj.text, "Canal borrado"); } SSL_write((*(conn + aux)).ssl, &auxMsj, sizeof(sms)); }else if(sscanf(str, "--kick %s", saux[0]) == 1){ // expulsión de un usuario // saux[0] es el nombre del usuario PDEBUG("INFO: expulsión de un usuario\n"); //PDEBUG("INFO: Moviendo usuarios\n"); //strcpy(saux[1], "general"); sms auxMsj; auxMsj.flag = SERV_EXIT; strcpy(auxMsj.name, SERVER); strcpy(auxMsj.text, "Usuario expulsado."); int aux = searchName(conn, connTam, saux[0]); SSL_write((*(conn+aux)).ssl, &auxMsj, sizeof(sms)); //moveAllTo(conn, &connTam, saux[0], rooms, dim, db, saux[1]); if(deleteRoom(saux[0], rooms, dim) == -1){ strcpy(auxMsj.text, "Error al borrar el canal, mire el log para más información"); }else{ strcpy(auxMsj.text, "Canal borrado"); } SSL_write((*(conn + aux)).ssl, &auxMsj, sizeof(sms)); }else if(sscanf(str, "--list-room") == 0){ // listando de canales sendRoomList((*(conn + aux)).ssl, rooms, dim); }else{ // error, comando no válido PDEBUG("INFO: Comando no válido\n"); sms auxMsj; auxMsj.flag = MSJ; strcpy(auxMsj.name, SERVER); strcpy(auxMsj.text, "Comando no válido"); SSL_write((*(conn + aux)).ssl, &auxMsj, sizeof(sms)); PDEBUG("INFO: Mensaje de comando no válido enviado al emisor\n"); return -1; } return 0; }