package server import ( "PD1/internal/protocol" "PD1/internal/utils/cryptoUtils" "PD1/internal/utils/networking" "log" ) //TODO: LOGGING SYSTEM func clientHandler(connection networking.Connection[protocol.Packet], dataStore DataStore) { defer connection.Conn.Close() //Get certificate sent by user clientCert := connection.GetPeerCertificate() //Get the OID values oidMap := cryptoUtils.ExtractAllOIDValues(clientCert) //Check if certificate usage is MSG SERVICE usage := oidMap["2.5.4.11"] if usage == "" { log.Println("User certificate does not have the correct usage") return } //Get the UID of this user UID := oidMap["2.5.4.65"] if UID == "" { log.Println("User certificate does not specify it's PSEUDONYM") } dataStore.storeUserCertIfNotExists(UID, *clientCert) F: for { pac, active := connection.Receive() if !active { break } switch pac.Flag { case protocol.FlagGetUserCert: reqUserCert := protocol.UnmarshalGetUserCert(pac.Body) userCertPacket := dataStore.GetUserCertificate(reqUserCert.UID) if !connection.Send(userCertPacket) { break F } case protocol.FlagGetUnreadMsgsInfo: getUnreadMsgsInfo := protocol.UnmarshalGetUnreadMsgsInfo(pac.Body) var messages protocol.Packet if getUnreadMsgsInfo.Page <= 0 || getUnreadMsgsInfo.PageSize <= 0 { messages = protocol.NewReportErrorPacket("Page and PageSize need to be >= 1") } else { messages = dataStore.GetUnreadMsgsInfo(UID, getUnreadMsgsInfo.Page, getUnreadMsgsInfo.PageSize) } if !connection.Send(messages) { break F } case protocol.FlagGetMsg: reqMsg := protocol.UnmarshalGetMsg(pac.Body) var message protocol.Packet if reqMsg.Num <= 0 { message = protocol.NewReportErrorPacket("Message NUM needs to be >= 1") } else { message = dataStore.GetMessage(UID, reqMsg.Num) } if !connection.Send(message) { break F } dataStore.MarkMessageInQueueAsRead(UID, reqMsg.Num) case protocol.FlagSendMsg: submitMsg := protocol.UnmarshalSendMsg(pac.Body) var answerSendMsgPacket protocol.Packet if submitMsg.ToUID == UID { answerSendMsgPacket = protocol.NewReportErrorPacket("Cannot message yourself") } else if !dataStore.userExists(submitMsg.ToUID) { answerSendMsgPacket = protocol.NewReportErrorPacket("Message receiver does not exist in database") } else { answerSendMsgPacket = dataStore.AddMessageToQueue(UID, submitMsg) } if !connection.Send(answerSendMsgPacket) { break F } } } } func Run(port int) { //Open connection to DB dataStore := OpenDB() defer dataStore.db.Close() //FIX: Get the server's keystore path instead of hardcoding it //Read server keystore password := readStdin("Insert keystore passphrase") serverKeyStore := cryptoUtils.LoadKeyStore("certs/server/server.p12", password) //Create server listener server := networking.NewServer[protocol.Packet](&serverKeyStore, port) go server.ListenLoop() for { //Receive Connection via channel conn := <-server.C //Launch client handler via clientHandler go clientHandler(conn, dataStore) } }