users can get each other's keys now

master
Jordan Orelli 10 years ago
parent c48700bf93
commit 83f5585c10

@ -33,16 +33,17 @@ type ReadWriter struct {
} }
type Client struct { type Client struct {
key *rsa.PrivateKey key *rsa.PrivateKey
host string host string
port int port int
nick string nick string
conn net.Conn conn net.Conn
done chan interface{} done chan interface{}
mu sync.Mutex mu sync.Mutex
prompt string prompt string
line []rune line []rune
prev *terminal.State prev *terminal.State
keyStore map[string]rsa.PublicKey
} }
// establishes a connection to the server // establishes a connection to the server
@ -89,6 +90,8 @@ func (c *Client) handleMessage(m Envelope) error {
return c.handleNote(m.Body) return c.handleNote(m.Body)
case "list-notes": case "list-notes":
return c.handleListNotes(m.Body) return c.handleListNotes(m.Body)
case "key-response":
return c.handleKeyResponse(m.Body)
default: default:
return fmt.Errorf("received message of unsupported type: %v", m.Kind) return fmt.Errorf("received message of unsupported type: %v", m.Kind)
} }
@ -284,11 +287,17 @@ func (c *Client) exec(line string) {
c.getNote(parts[1:]) c.getNote(parts[1:])
case "notes/list": case "notes/list":
c.listNotes(parts[1:]) c.listNotes(parts[1:])
case "keys/get":
c.getKey(parts[1:])
default: default:
c.err("unrecognized client command: %s", parts[0]) c.err("unrecognized client command: %s", parts[0])
} }
} }
// ------------------------------------------------------------------------------
// note functions
// ------------------------------------------------------------------------------
func (c *Client) createNote(args []string) { func (c *Client) createNote(args []string) {
if len(args) < 1 { if len(args) < 1 {
c.err("yeah you need to specify a title.") c.err("yeah you need to specify a title.")
@ -371,6 +380,41 @@ func (c *Client) encryptNote(title string, message []rune) (*EncryptedNote, erro
}, nil }, nil
} }
// ------------------------------------------------------------------------------
// key functions
// ------------------------------------------------------------------------------
func (c *Client) getKey(args []string) {
if len(args) != 1 {
c.err("keys/get takes exactly one arg")
return
}
req := KeyRequest(args[0])
if err := c.sendRequest(req); err != nil {
c.err("couldn't send key request: %v", err)
return
}
}
func (c *Client) saveKey(nick string, key rsa.PublicKey) {
if c.keyStore == nil {
c.keyStore = make(map[string]rsa.PublicKey, 8)
}
c.keyStore[nick] = key
}
func (c *Client) handleKeyResponse(body json.RawMessage) error {
c.info(string(body))
var res KeyResponse
if err := json.Unmarshal(body, &res); err != nil {
c.err(err.Error())
return err
}
c.info("%v", res)
c.saveKey(res.Nick, res.Key)
return nil
}
func (c *Client) readTextBlock() ([]rune, error) { func (c *Client) readTextBlock() ([]rune, error) {
// god dammit what have i gotten myself into // god dammit what have i gotten myself into
msg := make([]rune, 0, 400) msg := make([]rune, 0, 400)

59
db.go

@ -0,0 +1,59 @@
package main
import (
"crypto/rsa"
"encoding/json"
"fmt"
"github.com/syndtr/goleveldb/leveldb"
"sync"
)
var (
openDBs = make(map[string]userdb, 32)
dbopenlock sync.Mutex
)
type userdb struct {
*leveldb.DB
}
func (db *userdb) getPublicKey() (*rsa.PublicKey, error) {
val, err := db.Get([]byte("public_key"), nil)
if err != nil {
return nil, fmt.Errorf("unable to get public key: %v", err)
}
var key rsa.PublicKey
if err := json.Unmarshal(val, &key); err != nil {
return nil, fmt.Errorf("unable to get public key: %v", err)
}
return &key, nil
}
func getUserDB(nick string) (*userdb, error) {
if db, ok := openDBs[nick]; ok {
return &db, nil
}
path := fmt.Sprintf("./%s.db", nick)
conn, err := leveldb.OpenFile(path, nil)
if err != nil {
return nil, fmt.Errorf("unable to open db file at %s: %v", path, err)
}
info_log.Printf("opened database file: %s", path)
dbopenlock.Lock()
defer dbopenlock.Unlock()
db := userdb{conn}
openDBs[nick] = db
return &db, nil
}
func getUserKey(nick string) (*rsa.PublicKey, error) {
db, err := getUserDB(nick)
if err != nil {
return nil, err
}
return db.getPublicKey()
}

@ -121,3 +121,16 @@ type KeyRequest string
func (k KeyRequest) Kind() string { func (k KeyRequest) Kind() string {
return "key" return "key"
} }
func (k KeyRequest) Nick() string {
return string(k)
}
type KeyResponse struct {
Nick string
Key rsa.PublicKey
}
func (k KeyResponse) Kind() string {
return "key-response"
}

@ -32,7 +32,7 @@ type serverConnection struct {
conn net.Conn conn net.Conn
nick string nick string
key rsa.PublicKey key rsa.PublicKey
db *leveldb.DB db *userdb
} }
func (s *serverConnection) sendMeta(template string, args ...interface{}) { func (s *serverConnection) sendMeta(template string, args ...interface{}) {
@ -56,6 +56,8 @@ func (s *serverConnection) handleRequest(request Envelope) error {
return s.handleGetNoteRequest(request.Body) return s.handleGetNoteRequest(request.Body)
case "list-notes": case "list-notes":
return s.handleListNotesRequest(request.Body) return s.handleListNotesRequest(request.Body)
case "key":
return s.handleKeyRequest(request.Body)
default: default:
return fmt.Errorf("no such request type: %v", request.Kind) return fmt.Errorf("no such request type: %v", request.Kind)
} }
@ -84,6 +86,7 @@ func (s *serverConnection) handleAuthRequest(body json.RawMessage) error {
error_log.Printf("man fuck all this stupid key bullshit i hate it: %v", err) error_log.Printf("man fuck all this stupid key bullshit i hate it: %v", err)
break break
} }
info_log.Printf("saved key for user %s", auth.Nick)
case nil: case nil:
var key rsa.PublicKey var key rsa.PublicKey
if err := json.Unmarshal(b, &key); err != nil { if err := json.Unmarshal(b, &key); err != nil {
@ -193,13 +196,29 @@ func (s *serverConnection) handleListNotesRequest(body json.RawMessage) error {
return s.sendRequest(notes) return s.sendRequest(notes)
} }
func (s *serverConnection) handleKeyRequest(body json.RawMessage) error {
var req KeyRequest
if err := json.Unmarshal(body, &req); err != nil {
error_log.Printf("unable to read key request: %v", err)
return err
}
info_log.Printf("get key: %v", req.Nick())
key, err := getUserKey(req.Nick())
if err != nil {
return err
}
res := KeyResponse{
Nick: req.Nick(),
Key: *key,
}
return s.sendRequest(res)
}
func (s *serverConnection) openDB() error { func (s *serverConnection) openDB() error {
path := fmt.Sprintf("./%s.db", s.nick) db, err := getUserDB(s.nick)
db, err := leveldb.OpenFile(path, nil)
if err != nil { if err != nil {
return fmt.Errorf("unable to open db file at %s: %v", path, err) return err
} }
info_log.Printf("opened database file: %s", path)
s.db = db s.db = db
return nil return nil
} }

Loading…
Cancel
Save