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.Fatalln("User certificate does not have the correct usage") } //Get the UID of this user UID := oidMap["2.5.4.65"] if UID == "" { log.Fatalln("User certificate does not specify it's PSEUDONYM") } err := dataStore.storeUserCertIfNotExists(UID, *clientCert) if err != nil { log.Fatalln(err) } F: for { pac, err := connection.Receive() if err != nil { break } switch pac.Flag { case protocol.FlagGetUserCert: reqUserCert, err := protocol.UnmarshalGetUserCert(pac.Body) if err != nil { log.Fatalln(err) } userCertPacket := dataStore.GetUserCertificate(reqUserCert.UID) if err := connection.Send(userCertPacket); err != nil { log.Fatalln(err) break F } case protocol.FlagGetUnreadMsgsInfo: getUnreadMsgsInfo, err := protocol.UnmarshalGetUnreadMsgsInfo(pac.Body) if err != nil { log.Fatalln(err) } var messages protocol.Packet if getUnreadMsgsInfo.Page <= 0 || getUnreadMsgsInfo.PageSize <= 0 { messages = protocol.NewReportErrorPacket("Page and PageSize need to be >= 1") } else { messages, err = dataStore.GetUnreadMsgsInfo(UID, getUnreadMsgsInfo.Page, getUnreadMsgsInfo.PageSize) if err != nil { log.Fatalln(err) } } if err := connection.Send(messages); err != nil { log.Fatalln(err) } case protocol.FlagGetMsg: reqMsg, err := protocol.UnmarshalGetMsg(pac.Body) if err != nil { log.Fatalln(err) } 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 err := connection.Send(message); err != nil { log.Fatalln(err) break F } dataStore.MarkMessageInQueueAsRead(UID, reqMsg.Num) case protocol.FlagSendMsg: submitMsg, err := protocol.UnmarshalSendMsg(pac.Body) if err != nil { log.Fatalln(err) } var answerSendMsgPacket protocol.Packet if submitMsg.ToUID == UID { answerSendMsgPacket = protocol.NewReportErrorPacket("Message sender and receiver cannot be the same user") } else if !dataStore.userExists(submitMsg.ToUID) { answerSendMsgPacket = protocol.NewReportErrorPacket("Message receiver does not exist") } else { answerSendMsgPacket = dataStore.AddMessageToQueue(UID, submitMsg) } if err := connection.Send(answerSendMsgPacket); err != nil { log.Fatalln(err) break F } } } } func Run() { //Open connection to DB dataStore, err := OpenDB() if err != nil { log.Fatalln(err) } defer dataStore.db.Close() //Read server keystore keystorePassphrase := readStdin("Insert keystore passphrase") serverKeyStore, err := cryptoUtils.LoadKeyStore("certs/server/server.p12", keystorePassphrase) if err != nil { log.Fatalln(err) } //Create server listener server, err := networking.NewServer[protocol.Packet](&serverKeyStore) if err != nil { log.Fatalln(err) } go server.ListenLoop() for { //Receive Connection via channel conn := <-server.C //Launch client handler via clientHandler go clientHandler(conn, dataStore) } }