Resolved merge conflict

This commit is contained in:
sloum 2020-05-18 20:14:32 -07:00
commit 64590f53e7
6 changed files with 72 additions and 20 deletions

View File

@ -1 +1 @@
2.2.1 2.3.0

View File

@ -59,7 +59,7 @@ Displaying web content directly in \fBbombadillo\fP requires lynx, w3m or elinks
These commands work as a single keypress anytime \fBbombadillo\fP is not taking in a line based command or when the user is being prompted for action. This is the default command mode of \fBbombadillo\fP. These commands work as a single keypress anytime \fBbombadillo\fP is not taking in a line based command or when the user is being prompted for action. This is the default command mode of \fBbombadillo\fP.
.TP .TP
.B .B
b b, h
Navigate back one place in your document history. Navigate back one place in your document history.
.TP .TP
.B .B
@ -71,7 +71,7 @@ d
Scroll down an amount corresponding to 75% of your terminal window height in the current document. Scroll down an amount corresponding to 75% of your terminal window height in the current document.
.TP .TP
.B .B
f f, l
Navigate forward one place in your document history. Navigate forward one place in your document history.
.TP .TP
.B .B
@ -95,6 +95,7 @@ n
Jump to next found text item. Jump to next found text item.
.TP .TP
.B .B
N
Jump to previous found text item. Jump to previous found text item.
.TP .TP
.B .B

View File

@ -168,15 +168,15 @@ func (c *client) TakeControlInput() {
} else { } else {
c.goToLink(string(input)) c.goToLink(string(input))
} }
case 'j', 'J': case 'j':
// scroll down one line // scroll down one line
c.ClearMessage() c.ClearMessage()
c.Scroll(1) c.Scroll(1)
case 'k', 'K': case 'k':
// scroll up one line // scroll up one line
c.ClearMessage() c.ClearMessage()
c.Scroll(-1) c.Scroll(-1)
case 'q', 'Q': case 'q':
// quit bombadillo // quit bombadillo
cui.Exit(0, "") cui.Exit(0, "")
case 'g': case 'g':
@ -197,7 +197,7 @@ func (c *client) TakeControlInput() {
c.ClearMessage() c.ClearMessage()
distance := c.Height - c.Height/4 distance := c.Height - c.Height/4
c.Scroll(-distance) c.Scroll(-distance)
case 'b': case 'b', 'h':
// go back // go back
c.ClearMessage() c.ClearMessage()
err := c.PageState.NavigateHistory(-1) err := c.PageState.NavigateHistory(-1)
@ -222,7 +222,7 @@ func (c *client) TakeControlInput() {
// open the bookmarks browser // open the bookmarks browser
c.BookMarks.ToggleOpen() c.BookMarks.ToggleOpen()
c.Draw() c.Draw()
case 'f', 'F': case 'f', 'l':
// go forward // go forward
c.ClearMessage() c.ClearMessage()
err := c.PageState.NavigateHistory(1) err := c.PageState.NavigateHistory(1)
@ -711,11 +711,11 @@ func (c *client) search(query, url, question string) {
} }
switch u.Scheme { switch u.Scheme {
case "gopher": case "gopher":
go c.Visit(fmt.Sprintf("%s\t%s", u.Full, entry)) c.Visit(fmt.Sprintf("%s\t%s", u.Full, entry))
case "gemini": case "gemini":
// TODO url escape the entry variable // TODO url escape the entry variable
escapedEntry := entry escapedEntry := entry
go c.Visit(fmt.Sprintf("%s?%s", u.Full, escapedEntry)) c.Visit(fmt.Sprintf("%s?%s", u.Full, escapedEntry))
case "http", "https": case "http", "https":
c.Visit(u.Full) c.Visit(u.Full)
default: default:

View File

@ -49,8 +49,8 @@ func (t *TofuDigest) Purge(host string) error {
return fmt.Errorf("Invalid host %q", host) return fmt.Errorf("Invalid host %q", host)
} }
func (t *TofuDigest) Add(host, hash string) { func (t *TofuDigest) Add(host, hash string, time int64) {
t.certs[strings.ToLower(host)] = hash t.certs[strings.ToLower(host)] = fmt.Sprintf("%s|%d", hash, time)
} }
func (t *TofuDigest) Exists(host string) bool { func (t *TofuDigest) Exists(host string) bool {
@ -67,12 +67,11 @@ func (t *TofuDigest) Find(host string) (string, error) {
return "", fmt.Errorf("Invalid hostname, no key saved") return "", fmt.Errorf("Invalid hostname, no key saved")
} }
func (t *TofuDigest) Match(host string, cState *tls.ConnectionState) error { func (t *TofuDigest) Match(host, localCert string, cState *tls.ConnectionState) error {
host = strings.ToLower(host)
now := time.Now() now := time.Now()
for _, cert := range cState.PeerCertificates { for _, cert := range cState.PeerCertificates {
if t.certs[host] != hashCert(cert.Raw) { if localCert != hashCert(cert.Raw) {
continue continue
} }
@ -118,13 +117,40 @@ func (t *TofuDigest) newCert(host string, cState *tls.ConnectionState) error {
continue continue
} }
t.Add(host, hashCert(cert.Raw)) t.Add(host, hashCert(cert.Raw), cert.NotAfter.Unix())
return nil return nil
} }
return fmt.Errorf(reasons.String()) return fmt.Errorf(reasons.String())
} }
func (t *TofuDigest) GetCertAndTimestamp(host string) (string, int64, error) {
certTs, err := t.Find(host)
if err != nil {
return "", -1, err
}
certTsSplit := strings.SplitN(certTs, "|", -1)
if len(certTsSplit) < 2 {
_ = t.Purge(host)
return certTsSplit[0], -1, fmt.Errorf("Invalid certstring, no delimiter")
}
ts, err := strconv.ParseInt(certTsSplit[1], 10, 64)
if err != nil {
_ = t.Purge(host)
return certTsSplit[0], -1, err
}
now := time.Now()
if ts < now.Unix() {
// Ignore error return here since an error would indicate
// the host does not exist and we have already checked for
// that and the desired outcome of the action is that the
// host will no longer exist, so we are good either way
_ = t.Purge(host)
return "", -1, fmt.Errorf("Expired cert")
}
return certTsSplit[0], ts, nil
}
func (t *TofuDigest) IniDump() string { func (t *TofuDigest) IniDump() string {
if len(t.certs) < 1 { if len(t.certs) < 1 {
return "" return ""
@ -176,9 +202,11 @@ func Retrieve(host, port, resource string, td *TofuDigest) (string, error) {
return "", fmt.Errorf("Insecure, no certificates offered by server") return "", fmt.Errorf("Insecure, no certificates offered by server")
} }
if td.Exists(host) { localCert, localTs, err := td.GetCertAndTimestamp(host)
if localTs > 0 {
// See if we have a matching cert // See if we have a matching cert
err := td.Match(host, &connState) err := td.Match(host, localCert, &connState)
if err != nil && err.Error() != "EXP" { if err != nil && err.Error() != "EXP" {
// If there is no match and it isnt because of an expiration // If there is no match and it isnt because of an expiration
// just return the error // just return the error

17
main.go
View File

@ -25,8 +25,10 @@ import (
"os" "os"
"os/signal" "os/signal"
"path/filepath" "path/filepath"
"strconv"
"strings" "strings"
"syscall" "syscall"
"time"
"tildegit.org/sloum/bombadillo/config" "tildegit.org/sloum/bombadillo/config"
"tildegit.org/sloum/bombadillo/cui" "tildegit.org/sloum/bombadillo/cui"
@ -132,7 +134,20 @@ func loadConfig() {
} }
for _, v := range settings.Certs { for _, v := range settings.Certs {
bombadillo.Certs.Add(v.Key, v.Value) // Remove expired certs
vals := strings.SplitN(v.Value, "|", -1)
if len(vals) < 2 {
continue
}
ts, err := strconv.ParseInt(vals[1], 10, 64)
now := time.Now()
if err != nil || now.Unix() > ts {
continue
}
// Satisfied that the cert is not expired
// or malformed: add to the current client
// instance
bombadillo.Certs.Add(v.Key, vals[0], ts)
} }
} }

10
page.go
View File

@ -70,7 +70,9 @@ func (p *Page) WrapContent(width int, color bool) {
p.RenderImage(width) p.RenderImage(width)
return return
} }
width = min(width, 100)
counter := 0 counter := 0
spacer := " "
var content strings.Builder var content strings.Builder
var esc strings.Builder var esc strings.Builder
escape := false escape := false
@ -124,7 +126,6 @@ func (p *Page) WrapContent(width int, color bool) {
content.WriteRune('\n') content.WriteRune('\n')
counter = 0 counter = 0
if p.Location.Mime == "1" { if p.Location.Mime == "1" {
spacer := " "
content.WriteString(spacer) content.WriteString(spacer)
counter += len(spacer) counter += len(spacer)
} }
@ -188,3 +189,10 @@ func MakePage(url Url, content string, links []string) Page {
p := Page{make([]string, 0), content, links, url, 0, make([]int, 0), "", 0, "", 40, false} p := Page{make([]string, 0), content, links, url, 0, make([]int, 0), "", 0, "", 40, false}
return p return p
} }
func min(a, b int) int {
if a < b {
return a
}
return b
}