envelopes can be openned

master
Jordan Orelli 10 years ago
parent 4201ebbe39
commit b2afb81f04

@ -12,6 +12,7 @@ import (
"io" "io"
"net" "net"
"os" "os"
"reflect"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
@ -36,7 +37,7 @@ type Client struct {
prev *terminal.State prev *terminal.State
keyStore map[string]rsa.PublicKey keyStore map[string]rsa.PublicKey
requestCount int requestCount int
outstanding map[int]chan Envelope outstanding map[int]chan request
} }
// establishes a connection to the server // establishes a connection to the server
@ -77,24 +78,23 @@ func (c *Client) handleMessages() {
// handle a message received from the server // handle a message received from the server
func (c *Client) handleMessage(m Envelope) error { func (c *Client) handleMessage(m Envelope) error {
c.info("received response for message %d", m.Id) c.info("received response for message %d", m.Id)
res, ok := c.outstanding[m.Id] p, ok := c.outstanding[m.Id]
if !ok { if !ok {
c.info("%v", m) c.info("%v", m)
c.err("received message corresponding to no known request id: %d", m.Id) c.err("received message corresponding to no known request id: %d", m.Id)
return fmt.Errorf("no such id: %d", m.Id) return fmt.Errorf("no such id: %d", m.Id)
} }
res <- m r, err := m.Open()
close(res) if err != nil {
p <- ErrorDoc(err.Error())
} else {
p <- r
}
close(p)
return nil return nil
} }
func (c *Client) handleNote(raw json.RawMessage) error { func (c *Client) handleNote(enote *EncryptedNote) error {
c.info("unmarshaling note...")
var enote EncryptedNote
if err := json.Unmarshal(raw, &enote); err != nil {
return fmt.Errorf("unable to unmarshal encrypted note: %v", err)
}
c.info("aes key ciphertext: %x", enote.Key) c.info("aes key ciphertext: %x", enote.Key)
key, err := rsa.DecryptPKCS1v15(rand.Reader, c.key, enote.Key) key, err := rsa.DecryptPKCS1v15(rand.Reader, c.key, enote.Key)
if err != nil { if err != nil {
@ -119,12 +119,7 @@ func (c *Client) handleNote(raw json.RawMessage) error {
return nil return nil
} }
func (c *Client) handleListNotes(raw json.RawMessage) error { func (c *Client) handleListNotes(notes ListNotesResponse) error {
var notes ListNotesResponse
if err := json.Unmarshal(raw, &notes); err != nil {
return fmt.Errorf("unable to unmarshal listnotes response: %v", err)
}
writeNoteTitle := func(id int, title string) { writeNoteTitle := func(id int, title string) {
c.mu.Lock() c.mu.Lock()
defer c.mu.Unlock() defer c.mu.Unlock()
@ -159,25 +154,20 @@ func (c *Client) handshake() error {
return err return err
} }
res := <-promise res := <-promise
switch res.Kind { switch v := res.(type) {
case "error": case *ErrorDoc:
var e ErrorDoc
if err := json.Unmarshal(res.Body, &e); err != nil {
return fmt.Errorf("cannot read server error: %v", err)
}
c.err("server error: %v", e.Error())
close(c.done) close(c.done)
case "bool": return v
c.info(string(res.Body)) case *Bool:
c.renderLine() c.renderLine()
return nil
default: default:
c.err("i dunno what to do with this")
close(c.done) close(c.done)
return fmt.Errorf("received response of unexpected type: %v", reflect.TypeOf(v))
} }
return err
} }
func (c *Client) sendRequest(r request) (chan Envelope, error) { func (c *Client) sendRequest(r request) (chan request, error) {
e, err := wrapRequest(c.requestCount, r) e, err := wrapRequest(c.requestCount, r)
if err != nil { if err != nil {
return nil, err return nil, err
@ -187,7 +177,7 @@ func (c *Client) sendRequest(r request) (chan Envelope, error) {
return nil, err return nil, err
} }
res := make(chan Envelope, 1) res := make(chan request, 1)
c.outstanding[c.requestCount] = res c.outstanding[c.requestCount] = res
c.requestCount++ c.requestCount++
c.info("sending json request: %s", b) c.info("sending json request: %s", b)
@ -344,23 +334,41 @@ func (c *Client) getNote(args []string) {
c.err("that doesn't look like an int: %v", err) c.err("that doesn't look like an int: %v", err)
return return
} }
res, err := c.sendRequest(GetNoteRequest{Id: id}) p, err := c.sendRequest(GetNoteRequest{Id: id})
if err != nil { if err != nil {
c.err("couldn't request note: %v", err) c.err("couldn't request note: %v", err)
return return
} }
e := <-res res := <-p
c.handleNote(e.Body) switch v := res.(type) {
case *EncryptedNote:
c.handleNote(v)
case *ErrorDoc:
c.err("error getting note: %v", v.Error())
c.renderLine()
default:
c.err("received response of unexpected type: %v", reflect.TypeOf(v))
c.renderLine()
}
} }
func (c *Client) listNotes(args []string) { func (c *Client) listNotes(args []string) {
r := &ListNotes{N: 10} r := &ListNotes{N: 10}
res, err := c.sendRequest(r) p, err := c.sendRequest(r)
if err != nil { if err != nil {
c.err("%v", err) c.err("%v", err)
} }
e := <-res res := <-p
c.handleListNotes(e.Body) switch v := res.(type) {
case *ListNotesResponse:
c.handleListNotes(*v)
case *ErrorDoc:
c.err("error retrieving list of notes: %v", v.Error())
c.renderLine()
default:
c.err("received response of unexpected type: %v", reflect.TypeOf(v))
c.renderLine()
}
} }
func (c *Client) encryptNote(title string, message []rune) (*EncryptedNote, error) { func (c *Client) encryptNote(title string, message []rune) (*EncryptedNote, error) {
@ -412,13 +420,21 @@ func (c *Client) fetchKey(args []string) {
return return
} }
req := KeyRequest(args[0]) req := KeyRequest(args[0])
res, err := c.sendRequest(req) p, err := c.sendRequest(req)
if err != nil { if err != nil {
c.err("couldn't send key request: %v", err) c.err("couldn't send key request: %v", err)
return return
} }
e := <-res res := <-p
c.handleKeyResponse(e.Body) switch v := res.(type) {
case *KeyResponse:
c.saveKey(v.Nick, v.Key)
case *ErrorDoc:
c.err("error fetching key: %v", v.Error())
default:
c.err("received response of unexpected type: %v", reflect.TypeOf(v))
}
c.renderLine()
} }
func (c *Client) saveKey(nick string, key rsa.PublicKey) { func (c *Client) saveKey(nick string, key rsa.PublicKey) {
@ -518,11 +534,10 @@ func (c *Client) sendMessage(args []string) {
func (c *Client) listMessages(args []string) { func (c *Client) listMessages(args []string) {
r := &ListMessages{N: 10} r := &ListMessages{N: 10}
promise, err := c.sendRequest(r) p, err := c.sendRequest(r)
if err != nil { if err != nil {
c.err("%v", err) c.err("%v", err)
} }
env := <-promise
writeMessageId := func(id int, from string) { writeMessageId := func(id int, from string) {
c.mu.Lock() c.mu.Lock()
@ -532,23 +547,29 @@ func (c *Client) listMessages(args []string) {
c.renderLine() c.renderLine()
} }
var res ListMessagesResponse res := <-p
if err := json.Unmarshal(env.Body, &res); err != nil { switch v := res.(type) {
c.err("couldn't read list messages response: %v", err) case *ErrorDoc:
return c.err("error getting message list: %v", v.Error())
} c.renderLine()
for _, item := range res { case *ListMessagesResponse:
key, err := c.rsaDecrypt(item.Key) for _, item := range *v {
if err != nil { key, err := c.rsaDecrypt(item.Key)
c.err("unable to read aes key: %v", err) if err != nil {
return c.err("unable to read aes key: %v", err)
} return
from, err := c.aesDecrypt(key, item.From) }
if err != nil { from, err := c.aesDecrypt(key, item.From)
c.err("unable to read message sender: %v", err) if err != nil {
return c.err("unable to read message sender: %v", err)
return
}
writeMessageId(item.Id, string(from))
} }
writeMessageId(item.Id, string(from)) default:
c.err("received response of unexpected type: %v", reflect.TypeOf(v))
c.renderLine()
return
} }
} }
@ -564,51 +585,53 @@ func (c *Client) getMessage(args []string) {
return return
} }
promise, err := c.sendRequest(GetMessage{Id: id}) p, err := c.sendRequest(GetMessage{Id: id})
if err != nil { if err != nil {
c.err("%v", err) c.err("%v", err)
return return
} }
raw := <-promise res := <-p
switch v := res.(type) {
case *Message:
key, err := c.rsaDecrypt(v.Key)
if err != nil {
c.err("%v", err)
return
}
var msg Message from, err := c.aesDecrypt(key, v.From)
if err := json.Unmarshal(raw.Body, &msg); err != nil { if err != nil {
c.err("%v", err) c.err("%v", err)
return return
} }
key, err := c.rsaDecrypt(msg.Key) text, err := c.aesDecrypt(key, v.Text)
if err != nil { if err != nil {
c.err("%v", err) c.err("%v", err)
return return
} }
from, err := c.aesDecrypt(key, msg.From) c.mu.Lock()
if err != nil { defer c.mu.Unlock()
c.err("%v", err)
return
}
text, err := c.aesDecrypt(key, msg.Text) c.trunc()
if err != nil { fmt.Print("\033[37m")
c.err("%v", err) fmt.Print("\rFrom: ")
return fmt.Print("\033[0m") // unset color choice
fmt.Println(string(from))
fmt.Print("\033[90m")
fmt.Println("--------------------------------------------------------------------------------")
fmt.Printf("\033[0m")
fmt.Println(string(text))
c.renderLine()
case *ErrorDoc:
c.err("error getting message: %v", v.Error())
c.renderLine()
default:
c.err("received response of unexpected type: %v", reflect.TypeOf(v))
c.renderLine()
} }
c.mu.Lock()
defer c.mu.Unlock()
c.trunc()
fmt.Print("\033[37m")
fmt.Print("\rFrom: ")
fmt.Print("\033[0m") // unset color choice
fmt.Println(string(from))
fmt.Print("\033[90m")
fmt.Println("--------------------------------------------------------------------------------")
fmt.Printf("\033[0m")
fmt.Println(string(text))
c.renderLine()
} }
func (c *Client) readTextBlock() ([]rune, error) { func (c *Client) readTextBlock() ([]rune, error) {
@ -778,7 +801,7 @@ func connect() {
done: make(chan interface{}), done: make(chan interface{}),
line: make([]rune, 0, 32), line: make([]rune, 0, 32),
keyStore: make(map[string]rsa.PublicKey, 8), keyStore: make(map[string]rsa.PublicKey, 8),
outstanding: make(map[int]chan Envelope), outstanding: make(map[int]chan request),
} }
client.run() client.run()
} }

Loading…
Cancel
Save