bpjm.go
· 3.8 KiB · Go
原始檔案
// go library to scope with the BPjM Censorship list
package Bpjm
import (
"net/url"
"regexp"
"crypto/md5"
"strings"
"bytes"
"io/ioutil"
"encoding/binary"
"io"
)
// BpjmEntry is a datastructure for BPjM List Entries
type BpjmEntry struct {
DomainMd5 []byte // Md5 sum of domain, with a leading http
PathMd5 []byte
Depth int32
}
// parseURL - takes an URL string as input and returns a pointer to an url.URL object
func ParseURL(ustr string) (u *url.URL, err error) {
u, err = url.Parse(ustr)
return u, err
}
// XtrctHost - takes a url object and returns the host
func XtrctHost(u *url.URL) (host string) {
return u.Host
}
// XtrctPath - takes an url object and returns the path
func XtrctPath(u *url.URL) (path string) {
return u.Path
}
// FilterHost - Filters host according to BPjM Host Filters
// effectivley it cuts away a leading 'www.' subdomain, if existing
func FilterHost(host string) (fhost string) {
re := regexp.MustCompile("^www.")
fhost = re.ReplaceAllString(host, "")
return fhost
}
// FilterPath - Filters path according to BPjM Path Filters
// effectivley cuts away the root directory from path, if existing
func FilterPath(path string) (fpath string) {
re := regexp.MustCompile("^/")
fpath = re.ReplaceAllString(path, "")
return fpath
}
// GenMd5 - Generates n MD5 checksum of a given string and returns the md5sum as array of bytes
func GenMd5(in string) (md5sum []byte) {
inb := []byte(in)
md5 := md5.Sum(inb)
for _, c := range md5 {
md5sum = append(md5sum, c)
}
return md5sum
}
// check - is a general error checking routine that panics on error
func check(err error) {
if err != nil {
panic(err)
}
}
// enumerate depth of a given URL
func EnumerateDepth(u *url.URL) (depth int32) {
path := XtrctPath(u)
i := len(strings.Split(path, "/"))
return int32(i)
}
// UrlToBpjmEntry - takes an URL string as input and returns a BpjmEntry object
func UrlToBpjmEntry(ustr string) (entry BpjmEntry) {
u, err := ParseURL(ustr)
check(err)
host := FilterHost( XtrctHost(u) )
path := FilterPath( XtrctPath(u) )
depth := EnumerateDepth(u)
e := BpjmEntry{
GenMd5("http://" + host),
GenMd5(path),
depth,
}
return e
}
// Load a binary BPjM ListFile from a Fritzbox
func LoadFritzBoxFile(filename string)(data []byte) {
//data, err := ioutil.ReadFile(filename)
data, _ = ioutil.ReadFile(filename)
/*
if err != nil {
panic(err)
}
*/
return data
}
// FritzBoxFile - datastructure to describe an Fritzbox BPjM File
type FritzBoxFile struct {
Magick []byte
EmbedFileName string
Size int
Records int
Entries []BpjmEntry
}
func ParseFritzBoxFile(data []byte)(FBF FritzBoxFile){
// set up a buffer we can work with
buffer := bytes.NewBuffer(data)
// get magick; first 5 bytes
magick := buffer.Next(5)
// get embedded filename; next 59 bytes; cut out the null bytes and make it a string
embedFileName := string( bytes.Trim(buffer.Next(59), string(0x00)) )
// get size of file in bytes
size := buffer.Len()
// prepager a list to store entries
var Entries []BpjmEntry
// init counter
n := 0
// for each entry in list...
for {
// ... read domain hash
d := make([]byte, 16)
_, err := buffer.Read(d)
if err != nil {
if err == io.EOF {
break
}
panic(err)
}
// ...read path hash
p := make([]byte, 16)
_, err = buffer.Read(p)
if err != nil {
if err == io.EOF {
break
}
panic(err)
}
//...read depth
i, err := binary.ReadUvarint(buffer)
if err != nil {
if err == io.EOF {
break
}
panic(err)
}
// parse read data into an BpjmEntry object
e := BpjmEntry{
d,
p,
int32(i),
}
// append object to list of objects
Entries = append(Entries, e)
// count
n++
}
// parse collected data into a FirtzBoxFile Object
FBF = FritzBoxFile{
magick,
embedFileName,
size,
n,
Entries,
}
// return the FBF Object
return FBF
}
| 1 | // go library to scope with the BPjM Censorship list |
| 2 | |
| 3 | package Bpjm |
| 4 | |
| 5 | import ( |
| 6 | "net/url" |
| 7 | "regexp" |
| 8 | "crypto/md5" |
| 9 | "strings" |
| 10 | "bytes" |
| 11 | "io/ioutil" |
| 12 | "encoding/binary" |
| 13 | "io" |
| 14 | ) |
| 15 | |
| 16 | // BpjmEntry is a datastructure for BPjM List Entries |
| 17 | type BpjmEntry struct { |
| 18 | DomainMd5 []byte // Md5 sum of domain, with a leading http |
| 19 | PathMd5 []byte |
| 20 | Depth int32 |
| 21 | } |
| 22 | |
| 23 | // parseURL - takes an URL string as input and returns a pointer to an url.URL object |
| 24 | func ParseURL(ustr string) (u *url.URL, err error) { |
| 25 | u, err = url.Parse(ustr) |
| 26 | return u, err |
| 27 | } |
| 28 | |
| 29 | // XtrctHost - takes a url object and returns the host |
| 30 | func XtrctHost(u *url.URL) (host string) { |
| 31 | return u.Host |
| 32 | } |
| 33 | |
| 34 | // XtrctPath - takes an url object and returns the path |
| 35 | func XtrctPath(u *url.URL) (path string) { |
| 36 | return u.Path |
| 37 | } |
| 38 | |
| 39 | // FilterHost - Filters host according to BPjM Host Filters |
| 40 | // effectivley it cuts away a leading 'www.' subdomain, if existing |
| 41 | func FilterHost(host string) (fhost string) { |
| 42 | re := regexp.MustCompile("^www.") |
| 43 | fhost = re.ReplaceAllString(host, "") |
| 44 | return fhost |
| 45 | } |
| 46 | |
| 47 | // FilterPath - Filters path according to BPjM Path Filters |
| 48 | // effectivley cuts away the root directory from path, if existing |
| 49 | func FilterPath(path string) (fpath string) { |
| 50 | re := regexp.MustCompile("^/") |
| 51 | fpath = re.ReplaceAllString(path, "") |
| 52 | return fpath |
| 53 | } |
| 54 | |
| 55 | // GenMd5 - Generates n MD5 checksum of a given string and returns the md5sum as array of bytes |
| 56 | func GenMd5(in string) (md5sum []byte) { |
| 57 | inb := []byte(in) |
| 58 | md5 := md5.Sum(inb) |
| 59 | for _, c := range md5 { |
| 60 | md5sum = append(md5sum, c) |
| 61 | } |
| 62 | return md5sum |
| 63 | } |
| 64 | |
| 65 | // check - is a general error checking routine that panics on error |
| 66 | func check(err error) { |
| 67 | if err != nil { |
| 68 | panic(err) |
| 69 | } |
| 70 | } |
| 71 | |
| 72 | // enumerate depth of a given URL |
| 73 | func EnumerateDepth(u *url.URL) (depth int32) { |
| 74 | path := XtrctPath(u) |
| 75 | i := len(strings.Split(path, "/")) |
| 76 | return int32(i) |
| 77 | } |
| 78 | |
| 79 | // UrlToBpjmEntry - takes an URL string as input and returns a BpjmEntry object |
| 80 | func UrlToBpjmEntry(ustr string) (entry BpjmEntry) { |
| 81 | u, err := ParseURL(ustr) |
| 82 | check(err) |
| 83 | host := FilterHost( XtrctHost(u) ) |
| 84 | path := FilterPath( XtrctPath(u) ) |
| 85 | depth := EnumerateDepth(u) |
| 86 | e := BpjmEntry{ |
| 87 | GenMd5("http://" + host), |
| 88 | GenMd5(path), |
| 89 | depth, |
| 90 | } |
| 91 | return e |
| 92 | } |
| 93 | |
| 94 | // Load a binary BPjM ListFile from a Fritzbox |
| 95 | func LoadFritzBoxFile(filename string)(data []byte) { |
| 96 | //data, err := ioutil.ReadFile(filename) |
| 97 | data, _ = ioutil.ReadFile(filename) |
| 98 | /* |
| 99 | if err != nil { |
| 100 | panic(err) |
| 101 | } |
| 102 | */ |
| 103 | return data |
| 104 | } |
| 105 | |
| 106 | // FritzBoxFile - datastructure to describe an Fritzbox BPjM File |
| 107 | type FritzBoxFile struct { |
| 108 | Magick []byte |
| 109 | EmbedFileName string |
| 110 | Size int |
| 111 | Records int |
| 112 | Entries []BpjmEntry |
| 113 | } |
| 114 | |
| 115 | func ParseFritzBoxFile(data []byte)(FBF FritzBoxFile){ |
| 116 | // set up a buffer we can work with |
| 117 | buffer := bytes.NewBuffer(data) |
| 118 | // get magick; first 5 bytes |
| 119 | magick := buffer.Next(5) |
| 120 | // get embedded filename; next 59 bytes; cut out the null bytes and make it a string |
| 121 | embedFileName := string( bytes.Trim(buffer.Next(59), string(0x00)) ) |
| 122 | // get size of file in bytes |
| 123 | size := buffer.Len() |
| 124 | // prepager a list to store entries |
| 125 | var Entries []BpjmEntry |
| 126 | // init counter |
| 127 | n := 0 |
| 128 | // for each entry in list... |
| 129 | for { |
| 130 | // ... read domain hash |
| 131 | d := make([]byte, 16) |
| 132 | _, err := buffer.Read(d) |
| 133 | if err != nil { |
| 134 | if err == io.EOF { |
| 135 | break |
| 136 | } |
| 137 | panic(err) |
| 138 | } |
| 139 | // ...read path hash |
| 140 | p := make([]byte, 16) |
| 141 | _, err = buffer.Read(p) |
| 142 | if err != nil { |
| 143 | if err == io.EOF { |
| 144 | break |
| 145 | } |
| 146 | panic(err) |
| 147 | } |
| 148 | //...read depth |
| 149 | i, err := binary.ReadUvarint(buffer) |
| 150 | if err != nil { |
| 151 | if err == io.EOF { |
| 152 | break |
| 153 | } |
| 154 | panic(err) |
| 155 | } |
| 156 | // parse read data into an BpjmEntry object |
| 157 | e := BpjmEntry{ |
| 158 | d, |
| 159 | p, |
| 160 | int32(i), |
| 161 | } |
| 162 | // append object to list of objects |
| 163 | Entries = append(Entries, e) |
| 164 | // count |
| 165 | n++ |
| 166 | } |
| 167 | // parse collected data into a FirtzBoxFile Object |
| 168 | FBF = FritzBoxFile{ |
| 169 | magick, |
| 170 | embedFileName, |
| 171 | size, |
| 172 | n, |
| 173 | Entries, |
| 174 | } |
| 175 | // return the FBF Object |
| 176 | return FBF |
| 177 | } |