freemail

package
v0.0.0-...-840fb12 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 1, 2025 License: AGPL-3.0 Imports: 24 Imported by: 0

Documentation

Overview

Package freemail provides anonymous email over Freenet/Hyphanet.

Index

Constants

View Source
const (
	AESKeySize   = 32 // AES-256
	AESBlockSize = 16
	RSAKeySize   = 2048
)

KeySize constants

View Source
const (
	// MailsiteVersion is the current mailsite format version
	MailsiteVersion = 1

	// MailsiteInsertInterval is the interval between mailsite updates
	MailsiteInsertInterval = 6 * time.Hour

	// MailsiteSlotCount is the number of mailsite slots to maintain
	MailsiteSlotCount = 10
)

Mailsite constants

View Source
const (
	DefaultSMTPPort = 3025
	DefaultIMAPPort = 3143
	DefaultWebPort  = 3080
)

Default ports

View Source
const (
	// RTSPollInterval is the interval between RTS polling attempts
	RTSPollInterval = 10 * time.Minute

	// RTSExpiration is the duration after which an RTS becomes invalid
	RTSExpiration = 24 * time.Hour

	// RTSMaxRetries is the maximum number of RTS send attempts
	RTSMaxRetries = 5

	// RTSVersion is the current RTS protocol version
	RTSVersion = 1
)

RTS (Ready-To-Send) protocol constants

View Source
const (
	// SlotExpiration is the duration after which a slot expires (7 days)
	SlotExpiration = 7 * 24 * time.Hour

	// PollAheadSlots is the number of slots to check beyond the last used
	PollAheadSlots = 5

	// MaxSlotRetries is the maximum number of fetch attempts per slot
	MaxSlotRetries = 3

	// SlotPollInterval is the interval between slot polling attempts
	SlotPollInterval = 5 * time.Minute
)

Slot configuration constants

View Source
const (
	// MaxMessageSize is the maximum message size in bytes
	MaxMessageSize = 1024 * 1024 // 1MB

	// TransportTimeout is the timeout for transport operations
	TransportTimeout = 5 * time.Minute

	// ChannelRefreshInterval is how often to check channel health
	ChannelRefreshInterval = 1 * time.Hour
)

Transport configuration

View Source
const ClientName = "GoFreemail"

ClientName is the client name

View Source
const FreemailDomain = "freemail"

FreemailDomain is the domain suffix for Freemail addresses

View Source
const Version = "0.1.0"

Version is the GoFreemail version

Variables

This section is empty.

Functions

func DecodeBase64

func DecodeBase64(data string) ([]byte, error)

DecodeBase64 decodes base64 string to bytes

func DecodePrivateKey

func DecodePrivateKey(pemData string) (*rsa.PrivateKey, error)

DecodePrivateKey decodes an RSA private key from PEM format

func DecodePublicKey

func DecodePublicKey(pemData string) (*rsa.PublicKey, error)

DecodePublicKey decodes an RSA public key from PEM format

func DecryptAES

func DecryptAES(ciphertext, key, iv []byte) ([]byte, error)

DecryptAES decrypts data using AES-256-CBC

func DecryptRSA

func DecryptRSA(ciphertext []byte, privateKey *rsa.PrivateKey) ([]byte, error)

DecryptRSA decrypts data using RSA-OAEP with SHA-256

func EncodeBase64

func EncodeBase64(data []byte) string

EncodeBase64 encodes bytes to base64 string

func EncodePrivateKey

func EncodePrivateKey(privateKey *rsa.PrivateKey) string

EncodePrivateKey encodes an RSA private key to PEM format

func EncodePublicKey

func EncodePublicKey(publicKey *rsa.PublicKey) (string, error)

EncodePublicKey encodes an RSA public key to PEM format

func EncryptAES

func EncryptAES(plaintext, key, iv []byte) ([]byte, error)

EncryptAES encrypts data using AES-256-CBC

func EncryptRSA

func EncryptRSA(plaintext []byte, publicKey *rsa.PublicKey) ([]byte, error)

EncryptRSA encrypts data using RSA-OAEP with SHA-256

func GenerateAESKey

func GenerateAESKey() ([]byte, error)

GenerateAESKey generates a random AES-256 key

func GenerateIV

func GenerateIV() ([]byte, error)

GenerateIV generates a random initialization vector

func GenerateRSAKeyPair

func GenerateRSAKeyPair() (*rsa.PrivateKey, error)

GenerateRSAKeyPair generates a new RSA key pair

func HashSHA256

func HashSHA256(data []byte) []byte

HashSHA256 computes SHA-256 hash

func SerializeRTSMessage

func SerializeRTSMessage(msg *RTSMessage) []byte

SerializeRTSMessage serializes an RTS message for transmission

func SignSHA256

func SignSHA256(data []byte, privateKey *rsa.PrivateKey) ([]byte, error)

SignSHA256 creates a SHA-256 signature using RSA-PSS

func VerifySHA256

func VerifySHA256(data, signature []byte, publicKey *rsa.PublicKey) error

VerifySHA256 verifies a SHA-256 signature using RSA-PSS

Types

type Account

type Account struct {

	// Identity
	ID         string // WoT identity (Base64)
	Nickname   string
	RequestURI string
	InsertURI  string

	// Email
	EmailLocal string // Local part of email address

	// Authentication
	PasswordHash string // MD5 hash of password

	// Keys
	Keys *AccountKeys

	// Folders
	Inbox  *Folder
	Sent   *Folder
	Trash  *Folder
	Drafts *Folder

	// Custom folders
	Folders map[string]*Folder

	// Channels
	Channels map[string]*Channel

	// State
	LastLogin time.Time
	Created   time.Time
	// contains filtered or unexported fields
}

Account represents a Freemail account

func NewAccount

func NewAccount(id string, nickname string) *Account

NewAccount creates a new account

func (*Account) CreateFolder

func (a *Account) CreateFolder(name string) (*Folder, error)

CreateFolder creates a new folder

func (*Account) DeleteFolder

func (a *Account) DeleteFolder(name string) error

DeleteFolder deletes a folder

func (*Account) GetEmailAddress

func (a *Account) GetEmailAddress() *EmailAddress

GetEmailAddress returns the Freemail address for this account

func (*Account) GetFolder

func (a *Account) GetFolder(name string) *Folder

GetFolder returns a folder by name

func (*Account) ListFolders

func (a *Account) ListFolders() []string

ListFolders returns all folder names

type AccountKeys

type AccountKeys struct {
	// RSA keypair for signing and decryption
	PrivateKey *rsa.PrivateKey
	PublicKey  *rsa.PublicKey

	// RTS key for Ready-To-Send protocol
	RTSKey string

	// Mailsite URI
	MailsiteURI  string
	MailsiteSlot int
}

AccountKeys holds the cryptographic keys for an account

type AccountManager

type AccountManager struct {
	// contains filtered or unexported fields
}

AccountManager manages multiple accounts

func NewAccountManager

func NewAccountManager(storage *Storage) *AccountManager

NewAccountManager creates a new account manager

func (*AccountManager) Authenticate

func (am *AccountManager) Authenticate(id, password string) (*Account, bool)

Authenticate verifies credentials

func (*AccountManager) CreateAccount

func (am *AccountManager) CreateAccount(id, nickname, password string) (*Account, error)

CreateAccount creates a new account

func (*AccountManager) GetAccount

func (am *AccountManager) GetAccount(id string) *Account

GetAccount returns an account by ID

func (*AccountManager) GetAccountByEmail

func (am *AccountManager) GetAccountByEmail(email string) *Account

GetAccountByEmail finds an account by email address

func (*AccountManager) GetAccounts

func (am *AccountManager) GetAccounts() []*Account

GetAccounts returns all accounts

func (*AccountManager) LoadAccounts

func (am *AccountManager) LoadAccounts() error

LoadAccounts loads all accounts from storage

type AccountStorage

type AccountStorage struct {
	// contains filtered or unexported fields
}

AccountStorage handles account persistence

func (*AccountStorage) DeleteMessage

func (as *AccountStorage) DeleteMessage(folder *Folder, uid uint32) error

DeleteMessage deletes a message from storage

func (*AccountStorage) GetOutboxStorage

func (as *AccountStorage) GetOutboxStorage() *OutboxStorage

GetOutboxStorage returns outbox storage for an account

func (*AccountStorage) Initialize

func (as *AccountStorage) Initialize() error

Initialize creates account directories

func (*AccountStorage) LoadAccount

func (as *AccountStorage) LoadAccount() (*Account, error)

LoadAccount loads account properties

func (*AccountStorage) SaveAccount

func (as *AccountStorage) SaveAccount(account *Account) error

SaveAccount persists account properties

func (*AccountStorage) SaveChannel

func (as *AccountStorage) SaveChannel(channel *Channel) error

SaveChannel persists a channel

func (*AccountStorage) SaveFolder

func (as *AccountStorage) SaveFolder(folder *Folder) error

SaveFolder persists folder metadata

func (*AccountStorage) SaveMessage

func (as *AccountStorage) SaveMessage(folder *Folder, msg *Message) error

SaveMessage saves a message to a folder

type CachedMailsite

type CachedMailsite struct {
	Data      *MailsiteData
	FetchedAt time.Time
	Edition   int64
}

CachedMailsite represents a cached mailsite

type Channel

type Channel struct {

	// Identity
	ID             string // Channel identifier
	RemoteIdentity string // Remote user's WoT identity
	RemoteNickname string

	// Keys
	AESKey []byte // Symmetric key for this channel
	AESIV  []byte // Initialization vector

	// Slots
	SenderSlot   int
	ReceiverSlot int

	// State
	State     ChannelState
	CreatedAt time.Time
	ExpiresAt time.Time
	LastUsed  time.Time

	// Message queue
	Outbox []*OutgoingMessage
	// contains filtered or unexported fields
}

Channel represents a communication channel with another Freemail user

func NewChannel

func NewChannel(remoteIdentity string) *Channel

NewChannel creates a new channel

func (*Channel) IsExpired

func (c *Channel) IsExpired() bool

IsExpired checks if the channel has expired

func (*Channel) QueueMessage

func (c *Channel) QueueMessage(msg *Message, recipientID string) *OutgoingMessage

QueueMessage adds a message to the outbox

type ChannelState

type ChannelState int

ChannelState represents the state of a channel

const (
	ChannelActive ChannelState = iota
	ChannelReadOnly
	ChannelInactive
)

type ChannelTransport

type ChannelTransport struct {
	// contains filtered or unexported fields
}

ChannelTransport manages message transport for a single channel

func NewChannelTransport

func NewChannelTransport(channel *Channel, privateKey *rsa.PrivateKey, remotePublicKey *rsa.PublicKey) *ChannelTransport

NewChannelTransport creates a new channel transport

func (*ChannelTransport) DecryptMessage

func (ct *ChannelTransport) DecryptMessage(encrypted *EncryptedMessage, senderPublicKey *rsa.PublicKey) (*TransportMessage, error)

DecryptMessage decrypts a received message

func (*ChannelTransport) EncryptMessage

func (ct *ChannelTransport) EncryptMessage(msg *TransportMessage) (*EncryptedMessage, error)

EncryptMessage encrypts a message for transmission

func (*ChannelTransport) GetPendingMessages

func (ct *ChannelTransport) GetPendingMessages() []*TransportMessage

GetPendingMessages returns messages waiting to be sent

func (*ChannelTransport) MarkMessageSent

func (ct *ChannelTransport) MarkMessageSent(msgID string, slotNumber int)

MarkMessageSent marks a message as sent and removes from queue

func (*ChannelTransport) ProcessReceivedMessage

func (ct *ChannelTransport) ProcessReceivedMessage(encrypted *EncryptedMessage, senderPublicKey *rsa.PublicKey) (*TransportMessage, error)

ProcessReceivedMessage processes a received encrypted message

func (*ChannelTransport) QueueMessage

func (ct *ChannelTransport) QueueMessage(subject string, body []byte, senderID, recipientID string) *TransportMessage

QueueMessage queues a message for sending

func (*ChannelTransport) SetMessageReceivedCallback

func (ct *ChannelTransport) SetMessageReceivedCallback(callback func(msg *TransportMessage))

SetMessageReceivedCallback sets the callback for received messages

func (*ChannelTransport) SetMessageSentCallback

func (ct *ChannelTransport) SetMessageSentCallback(callback func(msg *TransportMessage))

SetMessageSentCallback sets the callback for sent messages

func (*ChannelTransport) SetSendSlots

func (ct *ChannelTransport) SetSendSlots(slots *SlotRange)

SetSendSlots sets the slot range for sending

type EmailAddress

type EmailAddress struct {
	Local    string // Local part (username)
	Identity string // WoT identity hash (Base32)
	Domain   string // Always "freemail"
}

EmailAddress represents a Freemail email address

func NewEmailAddress

func NewEmailAddress(local string, identityBase64 string) *EmailAddress

NewEmailAddress creates an email address from components

func ParseEmailAddress

func ParseEmailAddress(addr string) (*EmailAddress, error)

ParseEmailAddress parses a Freemail address

func (*EmailAddress) IdentityBase64

func (e *EmailAddress) IdentityBase64() (string, error)

IdentityBase64 returns the identity in Base64 format

func (*EmailAddress) String

func (e *EmailAddress) String() string

String returns the full email address

type EncryptedMessage

type EncryptedMessage struct {
	EncryptedKey  []byte // RSA-encrypted AES key
	IV            []byte // AES initialization vector
	EncryptedBody []byte // AES-encrypted message body
	Signature     []byte // RSA-PSS signature of encrypted body
}

EncryptedMessage represents an encrypted Freemail message

func DeserializeEncryptedMessage

func DeserializeEncryptedMessage(data []byte) (*EncryptedMessage, error)

DeserializeEncryptedMessage parses bytes into an EncryptedMessage

func (*EncryptedMessage) Serialize

func (em *EncryptedMessage) Serialize() []byte

Serialize converts EncryptedMessage to bytes for transmission

type FCPInterface

type FCPInterface interface {
	// InsertData inserts data to a key
	InsertData(key string, data []byte) error

	// FetchData fetches data from a key
	FetchData(key string) ([]byte, error)

	// GetPublicKey retrieves a public key for an identity
	GetPublicKey(identity string) (*rsa.PublicKey, error)
}

FCPInterface defines the interface for Freenet operations

type Folder

type Folder struct {
	Name        string
	Path        string // Full path (e.g., "INBOX.Subfolder")
	UIDValidity uint32
	NextUID     uint32
	Messages    []*Message
	Subfolders  []*Folder
	// contains filtered or unexported fields
}

Folder represents a mailbox folder

func NewFolder

func NewFolder(name string) *Folder

NewFolder creates a new folder

func (*Folder) AddMessage

func (f *Folder) AddMessage(msg *Message) uint32

AddMessage adds a message to the folder

func (*Folder) Count

func (f *Folder) Count() int

Count returns the number of messages

func (*Folder) Expunge

func (f *Folder) Expunge() []uint32

Expunge removes messages marked as deleted

func (*Folder) GetMessage

func (f *Folder) GetMessage(uid uint32) *Message

GetMessage returns a message by UID

func (*Folder) GetMessageBySeq

func (f *Folder) GetMessageBySeq(seq int) *Message

GetMessageBySeq returns a message by sequence number (1-based)

type Header struct {
	Name  string
	Value string
}

Header represents an email header

type Mailsite

type Mailsite struct {
	// contains filtered or unexported fields
}

Mailsite manages mailsite publishing and retrieval

func NewMailsite

func NewMailsite(identity, nickname, insertURI, requestURI, rtsKey, publicKeyPEM string) *Mailsite

NewMailsite creates a new mailsite manager

func (*Mailsite) BuildMailsiteData

func (m *Mailsite) BuildMailsiteData() *MailsiteData

BuildMailsiteData creates the mailsite data structure

func (*Mailsite) GetNextSlot

func (m *Mailsite) GetNextSlot() int

GetNextSlot returns and increments the next slot number

func (*Mailsite) GetRTSKey

func (m *Mailsite) GetRTSKey() string

GetRTSKey returns the RTS key for receiving RTS messages

func (*Mailsite) GetRequestURI

func (m *Mailsite) GetRequestURI() string

GetRequestURI returns the mailsite request URI

func (*Mailsite) GetSlotBaseKey

func (m *Mailsite) GetSlotBaseKey() string

GetSlotBaseKey returns the base key for slot generation

func (*Mailsite) NeedsUpdate

func (m *Mailsite) NeedsUpdate() bool

NeedsUpdate checks if the mailsite needs to be updated

func (*Mailsite) Publish

func (m *Mailsite) Publish() error

Publish publishes the mailsite to Freenet

func (*Mailsite) SetInserter

func (m *Mailsite) SetInserter(inserter MailsiteInserter)

SetInserter sets the mailsite inserter

type MailsiteData

type MailsiteData struct {
	Version      int               `json:"version"`
	Identity     string            `json:"identity"`
	Nickname     string            `json:"nickname"`
	RTSKey       string            `json:"rts_key"`    // Key for receiving RTS messages
	PublicKeyPEM string            `json:"public_key"` // PEM-encoded RSA public key
	SlotInfo     *MailsiteSlotInfo `json:"slot_info"`
	UpdatedAt    int64             `json:"updated_at"`
}

MailsiteData represents the published mailsite information

type MailsiteDataFetcher

type MailsiteDataFetcher interface {
	// FetchMailsite fetches mailsite data from a USK
	FetchMailsite(uri string) ([]byte, int64, error)
}

MailsiteDataFetcher interface for fetching mailsite data

type MailsiteFetcher

type MailsiteFetcher struct {
	// contains filtered or unexported fields
}

MailsiteFetcher fetches mailsite data from Freenet

func NewMailsiteFetcher

func NewMailsiteFetcher(fetcher MailsiteDataFetcher) *MailsiteFetcher

NewMailsiteFetcher creates a new mailsite fetcher

func (*MailsiteFetcher) ClearCache

func (mf *MailsiteFetcher) ClearCache()

ClearCache clears all cached mailsites

func (*MailsiteFetcher) Fetch

func (mf *MailsiteFetcher) Fetch(uri string) (*MailsiteData, error)

Fetch fetches a mailsite, using cache if available

func (*MailsiteFetcher) GetCached

func (mf *MailsiteFetcher) GetCached(uri string) *MailsiteData

GetCached returns a cached mailsite without fetching

func (*MailsiteFetcher) InvalidateCache

func (mf *MailsiteFetcher) InvalidateCache(uri string)

InvalidateCache removes a mailsite from the cache

type MailsiteInserter

type MailsiteInserter interface {
	// InsertMailsite inserts mailsite data to a USK
	InsertMailsite(uri string, data []byte) error
}

MailsiteInserter interface for inserting mailsite data

type MailsitePublisher

type MailsitePublisher struct {
	// contains filtered or unexported fields
}

MailsitePublisher periodically publishes mailsite updates

func NewMailsitePublisher

func NewMailsitePublisher(mailsite *Mailsite) *MailsitePublisher

NewMailsitePublisher creates a new mailsite publisher

func (*MailsitePublisher) PublishNow

func (mp *MailsitePublisher) PublishNow() error

PublishNow immediately publishes the mailsite

func (*MailsitePublisher) Start

func (mp *MailsitePublisher) Start()

Start begins periodic mailsite publishing

func (*MailsitePublisher) Stop

func (mp *MailsitePublisher) Stop()

Stop stops the publisher

type MailsiteSlotInfo

type MailsiteSlotInfo struct {
	BaseKey   string `json:"base_key"`   // Base key for slot generation
	NextSlot  int    `json:"next_slot"`  // Next slot for incoming messages
	SlotCount int    `json:"slot_count"` // Number of active slots
}

MailsiteSlotInfo contains slot configuration for messaging

type Message

type Message struct {

	// Identity
	UID       uint32 // IMAP UID
	MessageID string // Message-ID header

	// Envelope
	From       *EmailAddress
	To         []*EmailAddress
	CC         []*EmailAddress
	BCC        []*EmailAddress
	Subject    string
	Date       time.Time
	InReplyTo  string
	References []string

	// Headers
	Headers []*Header

	// Content
	ContentType     string
	ContentEncoding string
	Body            []byte

	// MIME parts (for multipart messages)
	Parts []*MessagePart

	// Flags
	Flags MessageFlag

	// Metadata
	Size     int64
	Received time.Time
	// contains filtered or unexported fields
}

Message represents an email message

func NewMessage

func NewMessage() *Message

NewMessage creates a new message

func (*Message) AddHeader

func (m *Message) AddHeader(name, value string)

AddHeader adds a header to the message

func (*Message) ClearFlag

func (m *Message) ClearFlag(flag MessageFlag)

ClearFlag clears a message flag

func (*Message) GetHeader

func (m *Message) GetHeader(name string) string

GetHeader returns the value of a header

func (*Message) HasFlag

func (m *Message) HasFlag(flag MessageFlag) bool

HasFlag checks if a flag is set

func (*Message) SetFlag

func (m *Message) SetFlag(flag MessageFlag)

SetFlag sets a message flag

type MessageCrypto

type MessageCrypto struct {
	// contains filtered or unexported fields
}

MessageCrypto provides encryption/decryption for Freemail messages

func NewMessageCrypto

func NewMessageCrypto(privateKey *rsa.PrivateKey) *MessageCrypto

NewMessageCrypto creates a new MessageCrypto instance

func (*MessageCrypto) DecryptMessage

func (mc *MessageCrypto) DecryptMessage(encrypted *EncryptedMessage, senderPublicKey *rsa.PublicKey) ([]byte, error)

DecryptMessage decrypts a message from a sender

func (*MessageCrypto) EncryptMessage

func (mc *MessageCrypto) EncryptMessage(message []byte, recipientPublicKey *rsa.PublicKey) (*EncryptedMessage, error)

EncryptMessage encrypts a message for a recipient

type MessageFlag

type MessageFlag int

MessageFlag represents IMAP message flags

const (
	FlagNone MessageFlag = 0
	FlagSeen MessageFlag = 1 << iota
	FlagAnswered
	FlagFlagged
	FlagDeleted
	FlagDraft
	FlagRecent
)

func ParseFlags

func ParseFlags(flagStr string) MessageFlag

ParseFlags parses IMAP flag strings

func (MessageFlag) String

func (f MessageFlag) String() string

String returns the IMAP flag name

type MessagePart

type MessagePart struct {
	ContentType        string
	ContentEncoding    string
	ContentDisposition string
	Filename           string
	Body               []byte
}

MessagePart represents a MIME part

type OutboxStorage

type OutboxStorage struct {
	// contains filtered or unexported fields
}

OutboxStorage handles outgoing message persistence

func (*OutboxStorage) DeleteOutgoingMessage

func (obs *OutboxStorage) DeleteOutgoingMessage(recipientID, msgID string) error

DeleteOutgoingMessage removes an outgoing message

func (*OutboxStorage) SaveOutgoingMessage

func (obs *OutboxStorage) SaveOutgoingMessage(msg *OutgoingMessage) error

SaveOutgoingMessage saves an outgoing message

type OutgoingMessage

type OutgoingMessage struct {
	ID          string
	RecipientID string
	Message     *Message
	Retries     int
	NextRetry   time.Time
	SentAt      time.Time
}

OutgoingMessage represents a message waiting to be sent

type RTSEncoder

type RTSEncoder struct {
	// contains filtered or unexported fields
}

RTSEncoder handles encoding/decoding of RTS messages

func NewRTSEncoder

func NewRTSEncoder(privateKey *rsa.PrivateKey) *RTSEncoder

NewRTSEncoder creates a new RTS encoder

func (*RTSEncoder) DecodeRTS

func (e *RTSEncoder) DecodeRTS(message *RTSMessage, senderPublicKey *rsa.PublicKey) (*RTSPayloadData, []byte, []byte, error)

DecodeRTS decodes an incoming RTS message

func (*RTSEncoder) EncodeRTS

func (e *RTSEncoder) EncodeRTS(request *RTSRequest, recipientPublicKey *rsa.PublicKey) (*RTSMessage, error)

EncodeRTS encodes an RTS request for transmission

type RTSFetcher

type RTSFetcher struct {
	// contains filtered or unexported fields
}

RTSFetcher fetches incoming RTS messages from Freenet

func NewRTSFetcher

func NewRTSFetcher(rtsManager *RTSManager, fetcher RTSKeyFetcher, rtsKey string) *RTSFetcher

NewRTSFetcher creates a new RTS fetcher

func (*RTSFetcher) Start

func (rf *RTSFetcher) Start()

Start begins polling for RTS messages

func (*RTSFetcher) Stop

func (rf *RTSFetcher) Stop()

Stop stops the RTS fetcher

type RTSInserter

type RTSInserter interface {
	// InsertRTS inserts an RTS message to a key
	InsertRTS(key string, data []byte) error

	// GetPublicKey retrieves a public key for an identity
	GetPublicKey(identity string) (*rsa.PublicKey, error)
}

RTSInserter interface for inserting RTS data to Freenet

type RTSKeyFetcher

type RTSKeyFetcher interface {
	// FetchRTSKey fetches data from an RTS key
	FetchRTSKey(key string) ([]byte, error)

	// GetPublicKey retrieves a public key for an identity
	GetPublicKey(identity string) (*rsa.PublicKey, error)
}

RTSKeyFetcher interface for fetching RTS data from Freenet

type RTSManager

type RTSManager struct {
	// contains filtered or unexported fields
}

RTSManager manages RTS requests and responses

func NewRTSManager

func NewRTSManager(dataDir string, privateKey *rsa.PrivateKey) *RTSManager

NewRTSManager creates a new RTS manager

func (*RTSManager) AcceptRTS

func (rm *RTSManager) AcceptRTS(channelID string, aesKey, iv []byte) error

AcceptRTS accepts an incoming RTS and establishes the channel

func (*RTSManager) CleanExpired

func (rm *RTSManager) CleanExpired() int

CleanExpired removes expired RTS requests

func (*RTSManager) CreateRTS

func (rm *RTSManager) CreateRTS(recipientIdentity, recipientRTSKey, senderMailsiteURI, senderIdentity string) (*RTSRequest, error)

CreateRTS creates a new RTS request to initiate a channel

func (*RTSManager) EncodeRTSForSending

func (rm *RTSManager) EncodeRTSForSending(requestID string, recipientPublicKey *rsa.PublicKey) (*RTSMessage, error)

EncodeRTSForSending encodes an RTS request for transmission

func (*RTSManager) GetPendingRTS

func (rm *RTSManager) GetPendingRTS() []*RTSRequest

GetPendingRTS returns all pending RTS requests

func (*RTSManager) MarkRTSAccepted

func (rm *RTSManager) MarkRTSAccepted(requestID string)

MarkRTSAccepted marks an RTS as accepted (channel established)

func (*RTSManager) MarkRTSFailed

func (rm *RTSManager) MarkRTSFailed(requestID string, err string)

MarkRTSFailed marks an RTS as failed

func (*RTSManager) MarkRTSSent

func (rm *RTSManager) MarkRTSSent(requestID string)

MarkRTSSent marks an RTS as having been sent

func (*RTSManager) ProcessIncomingRTS

func (rm *RTSManager) ProcessIncomingRTS(message *RTSMessage, senderPublicKey *rsa.PublicKey) (*RTSPayloadData, error)

ProcessIncomingRTS processes an incoming RTS message

func (*RTSManager) RejectRTS

func (rm *RTSManager) RejectRTS(channelID string) error

RejectRTS rejects an incoming RTS

func (*RTSManager) SetChannelCallback

func (rm *RTSManager) SetChannelCallback(callback func(channelID string, remoteIdentity string, aesKey, iv []byte))

SetChannelCallback sets the callback for channel establishment

func (*RTSManager) SetRTSReceivedCallback

func (rm *RTSManager) SetRTSReceivedCallback(callback func(payload *RTSPayloadData, aesKey, iv []byte))

SetRTSReceivedCallback sets the callback for received RTS messages

type RTSMessage

type RTSMessage struct {
	// Encrypted with recipient's public key
	EncryptedAESKey []byte

	// Encrypted with AES key
	EncryptedPayload []byte

	// Signature
	Signature []byte
}

RTSMessage represents a Ready-To-Send message

func DeserializeRTSMessage

func DeserializeRTSMessage(data []byte) (*RTSMessage, error)

DeserializeRTSMessage deserializes an RTS message from bytes

type RTSPayload

type RTSPayload struct {
	SenderMailsiteURI string
	SenderIdentity    string
	RecipientIdentity string
	InitiatorSlot     int
	ResponderSlot     int
	Timestamp         int64
}

RTSPayload is the decrypted RTS payload

type RTSPayloadData

type RTSPayloadData struct {
	Version           int    `json:"version"`
	SenderMailsiteURI string `json:"sender_mailsite_uri"`
	SenderIdentity    string `json:"sender_identity"`
	RecipientIdentity string `json:"recipient_identity"`
	InitiatorSlot     int    `json:"initiator_slot"`
	ResponderSlot     int    `json:"responder_slot"`
	ChannelID         string `json:"channel_id"`
	Timestamp         int64  `json:"timestamp"`
}

RTSPayloadData is the data structure for RTS payload

type RTSRequest

type RTSRequest struct {
	ID                string    `json:"id"`
	RecipientIdentity string    `json:"recipient_identity"`
	RecipientRTSKey   string    `json:"recipient_rts_key"`
	SenderMailsiteURI string    `json:"sender_mailsite_uri"`
	SenderIdentity    string    `json:"sender_identity"`
	InitiatorSlot     int       `json:"initiator_slot"`
	ResponderSlot     int       `json:"responder_slot"`
	ChannelAESKey     []byte    `json:"channel_aes_key"`
	ChannelIV         []byte    `json:"channel_iv"`
	State             RTSState  `json:"state"`
	CreatedAt         time.Time `json:"created_at"`
	ExpiresAt         time.Time `json:"expires_at"`
	Retries           int       `json:"retries"`
	LastError         string    `json:"last_error,omitempty"`
}

RTSRequest represents an outgoing RTS request

func NewRTSRequest

func NewRTSRequest(recipientIdentity, recipientRTSKey, senderMailsiteURI, senderIdentity string) (*RTSRequest, error)

NewRTSRequest creates a new RTS request

func (*RTSRequest) IsExpired

func (r *RTSRequest) IsExpired() bool

IsExpired checks if the RTS request has expired

type RTSSender

type RTSSender struct {
	// contains filtered or unexported fields
}

RTSSender sends RTS messages to Freenet

func NewRTSSender

func NewRTSSender(rtsManager *RTSManager, inserter RTSInserter) *RTSSender

NewRTSSender creates a new RTS sender

func (*RTSSender) SendRTSNow

func (rs *RTSSender) SendRTSNow(requestID string) error

SendRTSNow immediately sends an RTS request

func (*RTSSender) Start

func (rs *RTSSender) Start()

Start begins sending pending RTS messages

func (*RTSSender) Stop

func (rs *RTSSender) Stop()

Stop stops the RTS sender

type RTSState

type RTSState int

RTSState represents the state of an RTS exchange

const (
	RTSPending  RTSState = iota // RTS sent, waiting for channel establishment
	RTSAccepted                 // RTS accepted, channel established
	RTSRejected                 // RTS rejected by recipient
	RTSExpired                  // RTS expired without response
	RTSFailed                   // RTS failed after max retries
)

func (RTSState) String

func (s RTSState) String() string

String returns the string representation of RTSState

type Slot

type Slot struct {
	Number    int       `json:"number"`
	State     SlotState `json:"state"`
	Key       string    `json:"key,omitempty"`        // Freenet key for this slot
	MessageID string    `json:"message_id,omitempty"` // ID of message in this slot
	UsedAt    time.Time `json:"used_at,omitempty"`
	ExpiresAt time.Time `json:"expires_at,omitempty"`
	Retries   int       `json:"retries"`
	LastError string    `json:"last_error,omitempty"`
}

Slot represents a message slot in a channel

func (*Slot) IsExpired

func (s *Slot) IsExpired() bool

IsExpired checks if the slot has expired

type SlotFetcher

type SlotFetcher interface {
	// FetchSlot fetches data from a slot key
	FetchSlot(key string) ([]byte, error)
}

SlotFetcher interface for fetching slot data from Freenet

type SlotManager

type SlotManager struct {
	// contains filtered or unexported fields
}

SlotManager manages slots for all channels

func NewSlotManager

func NewSlotManager(dataDir string) *SlotManager

NewSlotManager creates a new slot manager

func (*SlotManager) AllocateSendSlot

func (sm *SlotManager) AllocateSendSlot(channelID string) *Slot

AllocateSendSlot allocates a slot for sending a message

func (*SlotManager) CleanAllExpired

func (sm *SlotManager) CleanAllExpired() int

CleanAllExpired cleans expired slots in all channels

func (*SlotManager) GetPendingFetches

func (sm *SlotManager) GetPendingFetches() map[string][]int

GetPendingFetches returns all slots that need to be fetched across all channels

func (*SlotManager) GetSlotRange

func (sm *SlotManager) GetSlotRange(channelID, direction string) *SlotRange

GetSlotRange returns the slot range for a channel direction

func (*SlotManager) InitializeChannel

func (sm *SlotManager) InitializeChannel(channelID string, sendBaseKey, receiveBaseKey string)

InitializeChannel initializes slots for a new channel

func (*SlotManager) Load

func (sm *SlotManager) Load() error

Load loads slot state from disk

func (*SlotManager) MarkReceived

func (sm *SlotManager) MarkReceived(channelID string, slotNumber int, messageID string)

MarkReceived marks a receive slot as having received a message

func (*SlotManager) MarkSent

func (sm *SlotManager) MarkSent(channelID string, slotNumber int, messageID string)

MarkSent marks a send slot as having sent a message

func (*SlotManager) Save

func (sm *SlotManager) Save() error

Save persists slot state to disk

func (*SlotManager) SetMessageCallback

func (sm *SlotManager) SetMessageCallback(callback func(channelID string, slotNumber int, data []byte))

SetMessageCallback sets the callback for received messages

type SlotPoller

type SlotPoller struct {
	// contains filtered or unexported fields
}

SlotPoller polls for messages in slots

func NewSlotPoller

func NewSlotPoller(slotManager *SlotManager, fetcher SlotFetcher) *SlotPoller

NewSlotPoller creates a new slot poller

func (*SlotPoller) GetStats

func (sp *SlotPoller) GetStats() (fetched, errors int)

GetStats returns polling statistics

func (*SlotPoller) Start

func (sp *SlotPoller) Start()

Start begins polling for messages

func (*SlotPoller) Stop

func (sp *SlotPoller) Stop()

Stop stops the poller

type SlotRange

type SlotRange struct {

	// Base key for generating slot keys
	BaseKey string `json:"base_key"`

	// Slot tracking
	Slots    map[int]*Slot `json:"slots"`
	NextSlot int           `json:"next_slot"` // Next slot to use for sending
	LastUsed int           `json:"last_used"` // Last slot that had a message

	// Direction: "send" or "receive"
	Direction string `json:"direction"`
	// contains filtered or unexported fields
}

SlotRange represents a range of slots for a channel direction

func NewSlotRange

func NewSlotRange(baseKey string, direction string) *SlotRange

NewSlotRange creates a new slot range

func (*SlotRange) AllocateSlot

func (sr *SlotRange) AllocateSlot() *Slot

AllocateSlot allocates the next available slot for sending

func (*SlotRange) CleanExpired

func (sr *SlotRange) CleanExpired() int

CleanExpired removes expired slots

func (*SlotRange) GetSlot

func (sr *SlotRange) GetSlot(number int) *Slot

GetSlot returns a slot by number, creating it if necessary

func (*SlotRange) GetSlotsToFetch

func (sr *SlotRange) GetSlotsToFetch() []int

GetSlotsToFetch returns slot numbers that should be fetched (poll ahead)

func (*SlotRange) MarkExpired

func (sr *SlotRange) MarkExpired(number int)

MarkExpired marks a slot as expired

func (*SlotRange) MarkFailed

func (sr *SlotRange) MarkFailed(number int, err string)

MarkFailed marks a slot as failed after too many retries

func (*SlotRange) MarkUsed

func (sr *SlotRange) MarkUsed(number int, messageID string)

MarkUsed marks a slot as used

type SlotState

type SlotState int

SlotState represents the state of a message slot

const (
	SlotUnused SlotState = iota
	SlotUsed
	SlotExpired
	SlotFailed
)

func (SlotState) String

func (s SlotState) String() string

String returns the string representation of SlotState

type Storage

type Storage struct {
	// contains filtered or unexported fields
}

Storage provides persistent storage for Freemail

func NewStorage

func NewStorage(dataDir string) *Storage

NewStorage creates a new storage instance

func (*Storage) GetAccountStorage

func (s *Storage) GetAccountStorage(accountID string) *AccountStorage

GetAccountStorage returns storage for a specific account

func (*Storage) Initialize

func (s *Storage) Initialize() error

Initialize creates the necessary directories

func (*Storage) SaveMessage

func (s *Storage) SaveMessage(accountID, folderName string, msg *Message) error

SaveMessage saves a message to an account's folder (convenience method on Storage)

type TransportManager

type TransportManager struct {
	// contains filtered or unexported fields
}

TransportManager manages all channel transports

func NewTransportManager

func NewTransportManager(privateKey *rsa.PrivateKey, dataDir string) *TransportManager

NewTransportManager creates a new transport manager

func (*TransportManager) AcceptChannel

func (tm *TransportManager) AcceptChannel(channelID string, remoteIdentity string, aesKey, iv []byte) error

AcceptChannel accepts an incoming channel from an RTS

func (*TransportManager) CloseChannel

func (tm *TransportManager) CloseChannel(channelID string) error

CloseChannel closes a channel

func (*TransportManager) GetRTSManager

func (tm *TransportManager) GetRTSManager() *RTSManager

GetRTSManager returns the RTS manager

func (*TransportManager) GetSlotManager

func (tm *TransportManager) GetSlotManager() *SlotManager

GetSlotManager returns the slot manager

func (*TransportManager) GetTransport

func (tm *TransportManager) GetTransport(channelID string) *ChannelTransport

GetTransport returns the transport for a channel

func (*TransportManager) InitiateChannel

func (tm *TransportManager) InitiateChannel(recipientIdentity, recipientRTSKey, senderMailsiteURI, senderIdentity string) (string, error)

InitiateChannel initiates a new channel with a remote identity

func (*TransportManager) ListChannels

func (tm *TransportManager) ListChannels() []string

ListChannels returns all channel IDs

func (*TransportManager) Load

func (tm *TransportManager) Load() error

Load loads transport state

func (*TransportManager) ProcessIncomingData

func (tm *TransportManager) ProcessIncomingData(channelID string, slotNumber int, data []byte) (*TransportMessage, error)

ProcessIncomingData processes incoming data from a slot

func (*TransportManager) Save

func (tm *TransportManager) Save() error

Save persists transport state

func (*TransportManager) SendMessage

func (tm *TransportManager) SendMessage(channelID, subject string, body []byte, senderID, recipientID string) error

SendMessage sends a message through a channel

func (*TransportManager) SetChannelCreatedCallback

func (tm *TransportManager) SetChannelCreatedCallback(callback func(channelID string))

SetChannelCreatedCallback sets the callback for channel creation

func (*TransportManager) SetFCPInterface

func (tm *TransportManager) SetFCPInterface(fcp FCPInterface)

SetFCPInterface sets the FCP interface

func (*TransportManager) SetMailsiteFetcher

func (tm *TransportManager) SetMailsiteFetcher(fetcher *MailsiteFetcher)

SetMailsiteFetcher sets the mailsite fetcher

func (*TransportManager) SetMessageReceivedCallback

func (tm *TransportManager) SetMessageReceivedCallback(callback func(channelID string, msg *TransportMessage))

SetMessageReceivedCallback sets the global message received callback

type TransportMessage

type TransportMessage struct {
	ID          string            `json:"id"`
	ChannelID   string            `json:"channel_id"`
	SenderID    string            `json:"sender_id"`
	RecipientID string            `json:"recipient_id"`
	Subject     string            `json:"subject"`
	Body        []byte            `json:"body"`
	Headers     map[string]string `json:"headers,omitempty"`
	Timestamp   int64             `json:"timestamp"`
	SlotNumber  int               `json:"slot_number"`
}

TransportMessage represents a message in transit

func DeserializeTransportMessage

func DeserializeTransportMessage(data []byte) (*TransportMessage, error)

DeserializeTransportMessage parses JSON bytes into a TransportMessage

func NewTransportMessage

func NewTransportMessage(channelID, senderID, recipientID, subject string, body []byte) *TransportMessage

NewTransportMessage creates a new transport message

func (*TransportMessage) Serialize

func (tm *TransportMessage) Serialize() ([]byte, error)

Serialize converts the message to JSON bytes

Directories

Path Synopsis
Package imap implements an IMAP server for Freemail.
Package imap implements an IMAP server for Freemail.
Package smtp implements an SMTP server for Freemail.
Package smtp implements an SMTP server for Freemail.
Package web provides a web interface for Freemail.
Package web provides a web interface for Freemail.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL