CSI-ES-2324/Projs/PD1/internal/server/server.go

135 lines
3.5 KiB
Go

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)
}
}