Compare commits

...

4 Commits

Author SHA1 Message Date
Cedric Verstraeten
a2cebaf90b hot fix: wait for token in webrtc 2023-10-24 13:14:14 +02:00
Cedric Verstraeten
3f58f26dfd decrypt recordings through the UI automatically using the existing AES key, you can still use the decrypt action or openssl afterwards 2023-10-23 14:38:29 +02:00
Cedric Verstraeten
a8d5f56f1e hotfix - build error encryption key value 2023-10-23 11:07:54 +02:00
Cédric Verstraeten
1eb62d80c7 add encryption + end-to-end encryption to feature list 2023-10-23 10:59:13 +02:00
4 changed files with 58 additions and 8 deletions

View File

@@ -109,8 +109,10 @@ This repository contains everything you'll need to know about our core product,
- Single camera per instance (e.g. one container per camera).
- Primary and secondary stream setup (record full-res, stream low-res).
- Low resolution streaming through MQTT and full resolution streaming through WebRTC.
- End-to-end encryption through MQTT using RSA and AES.
- Ability to specifiy conditions: offline mode, motion region, time table, continuous recording, etc.
- Post- and pre-recording on motion detection.
- Encryption at rest using AES-256-CBC.
- Ability to create fragmented recordings, and streaming though HLS fMP4.
- [Deploy where you want](#how-to-run-and-deploy-a-kerberos-agent) with the tools you use: `docker`, `docker compose`, `ansible`, `terraform`, `kubernetes`, etc.
- Cloud storage/persistance: Kerberos Hub, Kerberos Vault and Dropbox. [(WIP: Minio, Storj, Google Drive, FTP etc.)](https://github.com/kerberos-io/agent/issues/95)

View File

@@ -42,7 +42,7 @@ type Config struct {
HubPrivateKey string `json:"hub_private_key" bson:"hub_private_key"`
HubSite string `json:"hub_site" bson:"hub_site"`
ConditionURI string `json:"condition_uri" bson:"condition_uri"`
Encryption *Encryption `json:"encryption,omitempty" bson:"encryption",omitempty`
Encryption *Encryption `json:"encryption,omitempty" bson:"encryption,omitempty"`
}
// Capture defines which camera type (Id) you are using (IP, USB or Raspberry Pi camera),

View File

@@ -1,7 +1,9 @@
package http
import (
"io"
"os"
"strconv"
jwt "github.com/appleboy/gin-jwt/v2"
"github.com/gin-contrib/pprof"
@@ -12,6 +14,7 @@ import (
"log"
_ "github.com/kerberos-io/agent/machinery/docs"
"github.com/kerberos-io/agent/machinery/src/encryption"
"github.com/kerberos-io/agent/machinery/src/models"
swaggerFiles "github.com/swaggo/files"
ginSwagger "github.com/swaggo/gin-swagger"
@@ -77,7 +80,7 @@ func StartServer(configDirectory string, configuration *models.Configuration, co
r.Use(static.Serve("/settings", static.LocalFile(configDirectory+"/www", true)))
r.Use(static.Serve("/login", static.LocalFile(configDirectory+"/www", true)))
r.Handle("GET", "/file/*filepath", func(c *gin.Context) {
Files(c, configDirectory)
Files(c, configDirectory, configuration)
})
// Run the api on port
@@ -87,8 +90,50 @@ func StartServer(configDirectory string, configuration *models.Configuration, co
}
}
func Files(c *gin.Context, configDirectory string) {
c.Header("Access-Control-Allow-Origin", "*")
c.Header("Content-Type", "video/mp4")
c.File(configDirectory + "/data/recordings" + c.Param("filepath"))
func Files(c *gin.Context, configDirectory string, configuration *models.Configuration) {
// Get File
filePath := configDirectory + "/data/recordings" + c.Param("filepath")
_, err := os.Open(filePath)
if err != nil {
c.JSON(404, gin.H{"error": "File not found"})
return
}
contents, err := os.ReadFile(filePath)
if err == nil {
// Get symmetric key
symmetricKey := configuration.Config.Encryption.SymmetricKey
// Decrypt file
if symmetricKey != "" {
// Read file
if err != nil {
c.JSON(404, gin.H{"error": "File not found"})
return
}
// Decrypt file
contents, err = encryption.AesDecrypt(contents, symmetricKey)
if err != nil {
c.JSON(404, gin.H{"error": "File not found"})
return
}
}
// Get fileSize from contents
fileSize := len(contents)
// Send file to gin
c.Header("Access-Control-Allow-Origin", "*")
c.Header("Content-Disposition", "attachment; filename="+filePath)
c.Header("Content-Type", "video/mp4")
c.Header("Content-Length", strconv.Itoa(fileSize))
// Send contents to gin
io.WriteString(c.Writer, string(contents))
} else {
c.JSON(404, gin.H{"error": "File not found"})
return
}
}

View File

@@ -208,7 +208,9 @@ func InitializeWebRTCConnection(configuration *models.Configuration, communicati
}
payload, err := models.PackageMQTTMessage(configuration, message)
if err == nil {
mqttClient.Publish("kerberos/hub/"+hubKey, 0, false, payload)
log.Log.Info("InitializeWebRTCConnection:" + string(candateBinary))
token := mqttClient.Publish("kerberos/hub/"+hubKey, 0, false, payload)
token.Wait()
} else {
log.Log.Info("HandleRequestConfig: something went wrong while sending acknowledge config to hub: " + string(payload))
}
@@ -233,7 +235,8 @@ func InitializeWebRTCConnection(configuration *models.Configuration, communicati
}
payload, err := models.PackageMQTTMessage(configuration, message)
if err == nil {
mqttClient.Publish("kerberos/hub/"+hubKey, 0, false, payload)
token := mqttClient.Publish("kerberos/hub/"+hubKey, 0, false, payload)
token.Wait()
} else {
log.Log.Info("HandleRequestConfig: something went wrong while sending acknowledge config to hub: " + string(payload))
}