Upgrade geth

Point to the new fork of geth.
This commit is contained in:
Andrea Maria Piana 2021-06-28 13:04:35 +02:00
parent c1db89e657
commit 36430257fd
55 changed files with 8127 additions and 67 deletions

13
extkeys/go.mod Normal file
View File

@ -0,0 +1,13 @@
module github.com/status-im/status-go/extkeys
go 1.13
replace github.com/ethereum/go-ethereum v1.9.5 => github.com/status-im/go-ethereum v1.9.5-status.7
require (
github.com/btcsuite/btcd v0.20.1-beta
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d
github.com/ethereum/go-ethereum v1.9.5
golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c
golang.org/x/text v0.3.2
)

102
extkeys/go.sum Normal file
View File

@ -0,0 +1,102 @@
bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8=
github.com/Azure/azure-pipeline-go v0.0.0-20180607212504-7571e8eb0876/go.mod h1:XA1kFWRVhSK+KNFiOhfv83Fv8L9achrP7OxIzeTn1Yg=
github.com/Azure/azure-storage-blob-go v0.0.0-20180712005634-eaae161d9d5e/go.mod h1:x2mtS6O3mnMEZOJp7d7oldh8IvatBrMfReiyQ+cKgKY=
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
github.com/allegro/bigcache v0.0.0-20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw=
github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d h1:yJzD/yFppdVCf6ApMkVy8cUxV0XrxdP9rVf6D87/Mng=
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg=
github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY=
github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY=
github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s=
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ=
github.com/dgrijalva/jwt-go v0.0.0-20170201225849-2268707a8f08/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/docker/docker v0.0.0-20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
github.com/elastic/gosigar v0.0.0-20180330100440-37f05ff46ffa/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs=
github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/gizak/termui v0.0.0-20170117222342-991cd3d38091/go.mod h1:PkJoWUt/zacQKysNfQtcw1RW+eK2SxkieVBtl+4ovLA=
github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
github.com/go-stack/stack v1.5.4/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/hashicorp/golang-lru v0.0.0-20160813221303-0a025b7e63ad/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/huin/goupnp v0.0.0-20161224104101-679507af18f3/go.mod h1:MZ2ZmwcBpvOoJ22IJsc7va19ZwoheaBk43rKg12SKag=
github.com/influxdata/influxdb v0.0.0-20180221223340-01288bdb0883/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY=
github.com/jackpal/go-nat-pmp v0.0.0-20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
github.com/julienschmidt/httprouter v0.0.0-20170430222011-975b5c4c7c21/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/karalabe/hid v0.0.0-20181128192157-d815e0c1a2e2/go.mod h1:YvbcH+3Wo6XPs9nkgTY3u19KXLauXW+J5nB7hEHuX0A=
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
github.com/maruel/panicparse v0.0.0-20160720141634-ad661195ed0e/go.mod h1:nty42YY5QByNC5MM7q/nj938VbgPU7avs45z6NClpxI=
github.com/mattn/go-colorable v0.1.0/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-isatty v0.0.0-20180830101745-3fb116b82035/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
github.com/naoina/toml v0.0.0-20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E=
github.com/nsf/termbox-go v0.0.0-20170211012700-3540b76b9c77/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ=
github.com/olekukonko/tablewriter v0.0.0-20170128050532-febf2d34b54a/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/opentracing/opentracing-go v0.0.0-20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/pborman/uuid v0.0.0-20170112150404-1b00554d8222/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34=
github.com/peterh/liner v0.0.0-20170902204657-a37ad3984311/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc=
github.com/pkg/errors v0.0.0-20171216070316-e881fd58d78e/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/prometheus v0.0.0-20170814170113-3101606756c5/go.mod h1:oAIUtOny2rjMX0OWN5vPR5/q/twIROJvdqnQKDdil/s=
github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho=
github.com/robertkrimen/otto v0.0.0-20170205013659-6a77b7cbc37d/go.mod h1:xvqspoSXJTIpemEonrMDFq6XzwHYYgToXWj5eRX1OtY=
github.com/rs/cors v0.0.0-20160617231935-a62a804a8a00/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
github.com/rs/xhandler v0.0.0-20160618193221-ed27b6fd6521/go.mod h1:RvLn4FgxWubrpZHtQLnOf6EwhN2hEMusxZOhcW9H3UQ=
github.com/status-im/go-ethereum v1.9.5-status.7 h1:DKH1GiF52LwaZaw6YDBliFEgm/JDsbIT+hn7ph6X94Q=
github.com/status-im/go-ethereum v1.9.5-status.7/go.mod h1:YyH5DKB6+z+Vaya7eIm67pnuPZ1oiUMbbsZW41ktN0g=
github.com/status-im/status-go/extkeys v1.0.0/go.mod h1:GdqJbrcpkNm5ZsSCpp+PdMxnXx+OcRBdm3PI0rs1FpU=
github.com/stretchr/testify v0.0.0-20170809224252-890a5c3458b4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/syndtr/goleveldb v0.0.0-20181128100959-b001fa50d6b2/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
github.com/uber/jaeger-client-go v0.0.0-20180607151842-f7e0d4744fa6/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
github.com/uber/jaeger-lib v0.0.0-20180615202729-a51202d6f4a7/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba h1:9bFeDpN3gTqNanMVqNcoR/pJQuP5uroC3t1D7eXozTE=
golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c h1:/nJuwDLoL/zrqY6gf57vxC+Pi+pZ8bfhpPkicO5H7W4=
golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20161208181325-20d25e280405 h1:829vOVxxusYHC+IqBtkX5mbKtsY9fheQiQn0MZRVLfQ=
gopkg.in/check.v1 v1.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c=
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20180302121509-abf0ba0be5d5/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns=
gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

4
go.mod
View File

@ -12,8 +12,6 @@ replace github.com/nfnt/resize => github.com/status-im/resize v0.0.0-20201215164
require (
github.com/beevik/ntp v0.2.0
github.com/btcsuite/btcd v0.22.0-beta
github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce
github.com/cenkalti/backoff/v3 v3.2.2
github.com/davecgh/go-spew v1.1.1
github.com/deckarep/golang-set v1.7.1
@ -54,6 +52,7 @@ require (
github.com/status-im/markdown v0.0.0-20201022101546-c0cbdd5763bf
github.com/status-im/migrate/v4 v4.6.2-status.2
github.com/status-im/rendezvous v1.3.2
github.com/status-im/status-go/extkeys v1.1.2
github.com/status-im/tcp-shaker v0.0.0-20191114194237-215893130501
github.com/stretchr/testify v1.7.0
github.com/syndtr/goleveldb v1.0.1-0.20210305035536-64b5b1c73954
@ -64,7 +63,6 @@ require (
go.uber.org/zap v1.15.0
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e
golang.org/x/image v0.0.0-20210220032944-ac19c3e999fb
golang.org/x/text v0.3.6
gopkg.in/go-playground/assert.v1 v1.2.1 // indirect
gopkg.in/go-playground/validator.v9 v9.31.0
gopkg.in/natefinch/lumberjack.v2 v2.0.0

1
go.sum
View File

@ -1311,6 +1311,7 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=

41
vendor/github.com/elastic/gosigar/.gitignore generated vendored Normal file
View File

@ -0,0 +1,41 @@
# Directories
/.vagrant
/.idea
/build
# Files
.DS_Store
/*.iml
*.h
# Editor swap files
*.swp
*.swo
*.swn
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so
*.exe
*.test
*.prof
*.pyc
*.swp
# Example binaries
examples/df/df
examples/df/df.exe
examples/free/free
examples/free/free.exe
examples/ps/ps
examples/ps/ps.exe
examples/ss/ss
examples/ss/ss.exe
examples/uptime/uptime
examples/uptime/uptime.exe
# Test Data
cgroup/testdata/*
!cgroup/testdata/*.zip

213
vendor/github.com/elastic/gosigar/CHANGELOG.md generated vendored Normal file
View File

@ -0,0 +1,213 @@
# elastic/gosigar Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Added
### Fixed
### Changed
### Deprecated
## [0.14.1]
### Fixed
- Fix unsupported devices for filesystem. [#159](https://github.com/elastic/gosigar/pull/159)
## [0.14.0]
### Addded
- Add darwin ARM support. [#152](https://github.com/elastic/gosigar/pull/152)
## [0.13.0]
### Added
- Add method of overriding the /sys/fs/cgroup hierarchy, for reading cgroup metrics inside Docker [#148](https://github.com/elastic/gosigar/pull/148)
## [0.12.0]
### Added
- Add `Cached` data to Memory [#145](https://github.com/elastic/gosigar/pull/145)
- Add `SysTypeName` support on Windows [#146](https://github.com/elastic/gosigar/pull/146)
## [0.11.0]
### Added
- Added support for AIX. [#133](https://github.com/elastic/gosigar/pull/133)
### Fixed
- Fixed the `ss` example by replacing the Logrus package with the stdlib `log` package. [#123](https://github.com/elastic/gosigar/issues/123) [#136](https://github.com/elastic/gosigar/pull/136)
- Replaced `bytePtrToString` and cleaned up darwin code. [#138](https://github.com/elastic/gosigar/issues/138) [#141](https://github.com/elastic/gosigar/pull/141)
## [0.10.5]
### Fixed
- Fixed uptime calculation under Windows. [#126](https://github.com/elastic/gosigar/pull/126)
- Fixed compilation issue for darwin/386. [#128](https://github.com/elastic/gosigar/pull/128)
### Changed
- Load DLLs only from Windows system directory. [#132](https://github.com/elastic/gosigar/pull/132)
## [0.10.4]
### Fixed
- Fixed a crash when splitting command-line arguments under Windows. [#124](https://github.com/elastic/gosigar/pull/124)
## [0.10.3]
### Fixed
- ProcState.Get() doesn't fail under Windows when it cannot obtain process ownership information. [#121](https://github.com/elastic/gosigar/pull/121)
## [0.10.2]
### Fixed
- Fix memory leak when getting process arguments. [#119](https://github.com/elastic/gosigar/pull/119)
## [0.10.1]
### Fixed
- Replaced the WMI queries with win32 apis due to high CPU usage. [#116](https://github.com/elastic/gosigar/pull/116)
## [0.10.0]
### Added
- List filesystems on Windows that have an access path but not an assigned letter. [#112](https://github.com/elastic/gosigar/pull/112)
### Fixed
- Added missing runtime import for FreeBSD. [#104](https://github.com/elastic/gosigar/pull/104)
- Handle nil command line in Windows processes. [#110](https://github.com/elastic/gosigar/pull/110)
## [0.9.0]
### Added
- Added support for huge TLB pages on Linux [#97](https://github.com/elastic/gosigar/pull/97)
- Added support for big endian platform [#100](https://github.com/elastic/gosigar/pull/100)
### Fixed
- Add missing method for OpenBSD [#99](https://github.com/elastic/gosigar/pull/99)
## [0.8.0]
### Added
- Added partial `getrusage` support for Windows to retrieve system CPU time and user CPU time. [#95](https://github.com/elastic/gosigar/pull/95)
- Added full `getrusage` support for Unix. [#95](https://github.com/elastic/gosigar/pull/95)
## [0.7.0]
### Added
- Added method stubs for process handling for operating system that are not supported
by gosigar. All methods return `ErrNotImplemented` on such systems. [#88](https://github.com/elastic/gosigar/pull/88)
### Fixed
- Fix freebsd build by using the common version of Get(pid). [#91](https://github.com/elastic/gosigar/pull/91)
### Changed
- Fixed issues in cgroup package by adding missing error checks and closing
file handles. [#92](https://github.com/elastic/gosigar/pull/92)
## [0.6.0]
### Added
- Added method stubs to enable compilation for operating systems that are not
supported by gosigar. All methods return `ErrNotImplemented` on these unsupported
operating systems. [#83](https://github.com/elastic/gosigar/pull/83)
- FreeBSD returns `ErrNotImplemented` for `ProcTime.Get`. [#83](https://github.com/elastic/gosigar/pull/83)
### Changed
- OpenBSD returns `ErrNotImplemented` for `ProcTime.Get` instead of `nil`. [#83](https://github.com/elastic/gosigar/pull/83)
- Fixed incorrect `Mem.Used` calculation under linux. [#82](https://github.com/elastic/gosigar/pull/82)
- Fixed `ProcState` on Linux and FreeBSD when process names contain parentheses. [#81](https://github.com/elastic/gosigar/pull/81)
### Removed
- Remove NetBSD build from sigar_unix.go as it is not supported by gosigar. [#83](https://github.com/elastic/gosigar/pull/83)
## [0.5.0]
### Changed
- Fixed Trim environment variables when comparing values in the test suite. [#79](https://github.com/elastic/gosigar/pull/79)
- Make `kern_procargs` more robust under darwin when we cannot retrieve
all the information about a process. [#78](https://github.com/elastic/gosigar/pull/78)
## [0.4.0]
### Changed
- Fixed Windows issue that caused a hang during `init()` if WMI wasn't ready. [#74](https://github.com/elastic/gosigar/pull/74)
## [0.3.0]
### Added
- Read `MemAvailable` value for kernel 3.14+ [#71](https://github.com/elastic/gosigar/pull/71)
## [0.2.0]
### Added
- Added `ErrCgroupsMissing` to indicate that /proc/cgroups is missing which is
an indicator that cgroups were disabled at compile time. [#64](https://github.com/elastic/gosigar/pull/64)
### Changed
- Changed `cgroup.SupportedSubsystems()` to honor the "enabled" column in the
/proc/cgroups file. [#64](https://github.com/elastic/gosigar/pull/64)
## [0.1.0]
### Added
- Added `CpuList` implementation for Windows that returns CPU timing information
on a per CPU basis. [#55](https://github.com/elastic/gosigar/pull/55)
- Added `Uptime` implementation for Windows. [#55](https://github.com/elastic/gosigar/pull/55)
- Added `Swap` implementation for Windows based on page file metrics. [#55](https://github.com/elastic/gosigar/pull/55)
- Added support to `github.com/gosigar/sys/windows` for querying and enabling
privileges in a process token.
- Added utility code for interfacing with linux NETLINK_INET_DIAG. [#60](https://github.com/elastic/gosigar/pull/60)
- Added `ProcEnv` for getting a process's environment variables. [#61](https://github.com/elastic/gosigar/pull/61)
### Changed
- Changed several `OpenProcess` calls on Windows to request the lowest possible
access privileges. [#50](https://github.com/elastic/gosigar/pull/50)
- Removed cgo usage from Windows code.
- Added OS version checks to `ProcArgs.Get` on Windows because the
`Win32_Process` WMI query is not available prior to Windows vista. On XP and
Windows 2003, this method returns `ErrNotImplemented`. [#55](https://github.com/elastic/gosigar/pull/55)
### Fixed
- Fixed value of `Mem.ActualFree` and `Mem.ActualUsed` on Windows. [#49](https://github.com/elastic/gosigar/pull/49)
- Fixed `ProcTime.StartTime` on Windows to report value in milliseconds since
Unix epoch. [#51](https://github.com/elastic/gosigar/pull/51)
- Fixed `ProcStatus.PPID` value is wrong on Windows. [#55](https://github.com/elastic/gosigar/pull/55)
- Fixed `ProcStatus.Username` error on Windows XP [#56](https://github.com/elastic/gosigar/pull/56)
[Unreleased]: https://github.com/elastic/gosigar/compare/v0.14.1...HEAD
[0.14.1]: https://github.com/elastic/gosigar/releases/tag/v0.14.1
[0.14.0]: https://github.com/elastic/gosigar/releases/tag/v0.14.0
[0.13.0]: https://github.com/elastic/gosigar/releases/tag/v0.13.0
[0.12.0]: https://github.com/elastic/gosigar/releases/tag/v0.12.0
[0.11.0]: https://github.com/elastic/gosigar/releases/tag/v0.11.0
[0.10.5]: https://github.com/elastic/gosigar/releases/tag/v0.10.5
[0.10.4]: https://github.com/elastic/gosigar/releases/tag/v0.10.4
[0.10.3]: https://github.com/elastic/gosigar/releases/tag/v0.10.3
[0.10.2]: https://github.com/elastic/gosigar/releases/tag/v0.10.2
[0.10.1]: https://github.com/elastic/gosigar/releases/tag/v0.10.1
[0.10.0]: https://github.com/elastic/gosigar/releases/tag/v0.10.0
[0.9.0]: https://github.com/elastic/gosigar/releases/tag/v0.9.0
[0.8.0]: https://github.com/elastic/gosigar/releases/tag/v0.8.0
[0.7.0]: https://github.com/elastic/gosigar/releases/tag/v0.7.0
[0.6.0]: https://github.com/elastic/gosigar/releases/tag/v0.6.0
[0.5.0]: https://github.com/elastic/gosigar/releases/tag/v0.5.0
[0.4.0]: https://github.com/elastic/gosigar/releases/tag/v0.4.0
[0.3.0]: https://github.com/elastic/gosigar/releases/tag/v0.3.0
[0.2.0]: https://github.com/elastic/gosigar/releases/tag/v0.2.0
[0.1.0]: https://github.com/elastic/gosigar/releases/tag/v0.1.0

201
vendor/github.com/elastic/gosigar/LICENSE generated vendored Normal file
View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

9
vendor/github.com/elastic/gosigar/NOTICE generated vendored Normal file
View File

@ -0,0 +1,9 @@
Copyright (c) [2009-2011] VMware, Inc. All Rights Reserved.
This product is licensed to you under the Apache License, Version 2.0 (the "License").
You may not use this product except in compliance with the License.
This product includes a number of subcomponents with
separate copyright notices and license terms. Your use of these
subcomponents is subject to the terms and conditions of the
subcomponent's license, as noted in the LICENSE file.

59
vendor/github.com/elastic/gosigar/README.md generated vendored Normal file
View File

@ -0,0 +1,59 @@
# Go sigar [![Build Status](https://beats-ci.elastic.co/job/Beats/job/gosigar/job/master/badge/icon)](https://beats-ci.elastic.co/job/Beats/job/gosigar/job/master/)
## Overview
Go sigar is a golang implementation of the
[sigar API](https://github.com/hyperic/sigar). The Go version of
sigar has a very similar interface, but is being written from scratch
in pure go/cgo, rather than cgo bindings for libsigar.
## Test drive
$ go get github.com/elastic/gosigar
$ cd $GOPATH/src/github.com/elastic/gosigar/examples/ps
$ go build
$ ./ps
## Supported platforms
The features vary by operating system.
| Feature | Linux | Darwin | Windows | OpenBSD | FreeBSD | AIX |
|-----------------|:-----:|:------:|:-------:|:-------:|:-------:|:-------:|
| Cpu | X | X | X | X | X | X |
| CpuList | X | X | | X | X | X |
| FDUsage | X | | | | X | |
| FileSystemList | X | X | X | X | X | X |
| FileSystemUsage | X | X | X | X | X | X |
| HugeTLBPages | X | | | | | |
| LoadAverage | X | X | | X | X | X |
| Mem | X | X | X | X | X | X |
| ProcArgs | X | X | X | | X | X |
| ProcEnv | X | X | | | X | X |
| ProcExe | X | X | | | X | X |
| ProcFDUsage | X | | | | X | |
| ProcList | X | X | X | | X | X |
| ProcMem | X | X | X | | X | X |
| ProcState | X | X | X | | X | X |
| ProcTime | X | X | X | | X | X |
| Rusage | X | | X | | | X |
| Swap | X | X | | X | X | X |
| Uptime | X | X | | X | X | X |
## OS Specific Notes
### FreeBSD
Mount both `linprocfs` and `procfs` for compatability. Consider adding these
mounts to your `/etc/fstab` file so they are mounted automatically at boot.
```
sudo mount -t procfs proc /proc
sudo mkdir -p /compat/linux/proc
sudo mount -t linprocfs /dev/null /compat/linux/proc
```
## License
Apache 2.0

25
vendor/github.com/elastic/gosigar/Vagrantfile generated vendored Normal file
View File

@ -0,0 +1,25 @@
# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box = "hashicorp/precise64"
config.vm.provision "shell", inline: "mkdir -p /home/vagrant/go"
config.vm.synced_folder ".", "/home/vagrant/go/src/github.com/cloudfoundry/gosigar"
config.vm.provision "shell", inline: "chown -R vagrant:vagrant /home/vagrant/go"
install_go = <<-BASH
set -e
if [ ! -d "/usr/local/go" ]; then
cd /tmp && wget https://storage.googleapis.com/golang/go1.3.3.linux-amd64.tar.gz
cd /usr/local
tar xvzf /tmp/go1.3.3.linux-amd64.tar.gz
echo 'export GOPATH=/home/vagrant/go; export PATH=/usr/local/go/bin:$PATH:$GOPATH/bin' >> /home/vagrant/.bashrc
fi
export GOPATH=/home/vagrant/go
export PATH=/usr/local/go/bin:$PATH:$GOPATH/bin
/usr/local/go/bin/go get -u github.com/onsi/ginkgo/ginkgo
/usr/local/go/bin/go get -u github.com/onsi/gomega;
BASH
config.vm.provision "shell", inline: 'apt-get install -y git-core'
config.vm.provision "shell", inline: install_go
end

21
vendor/github.com/elastic/gosigar/codecov.yml generated vendored Normal file
View File

@ -0,0 +1,21 @@
# Enable coverage report message for diff on commit
coverage:
status:
project: off
patch:
default:
# basic
target: auto
threshold: null
base: auto
# advanced
branches: null
if_no_uploads: error
if_not_found: success
if_ci_failed: error
only_pulls: false
flags: null
paths: null
# Disable comments on Pull Requests
comment: false

89
vendor/github.com/elastic/gosigar/concrete_sigar.go generated vendored Normal file
View File

@ -0,0 +1,89 @@
package gosigar
import (
"time"
)
type ConcreteSigar struct{}
func (c *ConcreteSigar) CollectCpuStats(collectionInterval time.Duration) (<-chan Cpu, chan<- struct{}) {
// samplesCh is buffered to 1 value to immediately return first CPU sample
samplesCh := make(chan Cpu, 1)
stopCh := make(chan struct{})
go func() {
var cpuUsage Cpu
// Immediately provide non-delta value.
// samplesCh is buffered to 1 value, so it will not block.
cpuUsage.Get()
samplesCh <- cpuUsage
ticker := time.NewTicker(collectionInterval)
for {
select {
case <-ticker.C:
previousCpuUsage := cpuUsage
cpuUsage.Get()
select {
case samplesCh <- cpuUsage.Delta(previousCpuUsage):
default:
// Include default to avoid channel blocking
}
case <-stopCh:
return
}
}
}()
return samplesCh, stopCh
}
func (c *ConcreteSigar) GetLoadAverage() (LoadAverage, error) {
l := LoadAverage{}
err := l.Get()
return l, err
}
func (c *ConcreteSigar) GetMem() (Mem, error) {
m := Mem{}
err := m.Get()
return m, err
}
func (c *ConcreteSigar) GetSwap() (Swap, error) {
s := Swap{}
err := s.Get()
return s, err
}
func (c *ConcreteSigar) GetHugeTLBPages() (HugeTLBPages, error) {
p := HugeTLBPages{}
err := p.Get()
return p, err
}
func (c *ConcreteSigar) GetFileSystemUsage(path string) (FileSystemUsage, error) {
f := FileSystemUsage{}
err := f.Get(path)
return f, err
}
func (c *ConcreteSigar) GetFDUsage() (FDUsage, error) {
fd := FDUsage{}
err := fd.Get()
return fd, err
}
// GetRusage return the resource usage of the process
// Possible params: 0 = RUSAGE_SELF, 1 = RUSAGE_CHILDREN, 2 = RUSAGE_THREAD
func (c *ConcreteSigar) GetRusage(who int) (Rusage, error) {
r := Rusage{}
err := r.Get(who)
return r, err
}

9
vendor/github.com/elastic/gosigar/go.mod generated vendored Normal file
View File

@ -0,0 +1,9 @@
module github.com/elastic/gosigar
go 1.14
require (
github.com/pkg/errors v0.9.1
github.com/stretchr/testify v1.4.0
golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0
)

15
vendor/github.com/elastic/gosigar/go.sum generated vendored Normal file
View File

@ -0,0 +1,15 @@
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0 h1:8H8QZJ30plJyIVj60H3lr8TZGIq2Fh3Cyrs/ZNg1foU=
golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

564
vendor/github.com/elastic/gosigar/sigar_aix.go generated vendored Normal file
View File

@ -0,0 +1,564 @@
// +build aix
package gosigar
/*
#cgo LDFLAGS: -L/usr/lib -lperfstat
#include <libperfstat.h>
#include <procinfo.h>
#include <unistd.h>
#include <utmp.h>
#include <sys/mntctl.h>
#include <sys/proc.h>
#include <sys/types.h>
#include <sys/vmount.h>
*/
import "C"
import (
"bytes"
"encoding/binary"
"fmt"
"io"
"os"
"os/user"
"runtime"
"strconv"
"syscall"
"time"
"unsafe"
)
var system struct {
ticks uint64
btime uint64
pagesize uint64
}
func init() {
// sysconf(_SC_CLK_TCK) returns the number of ticks by second.
system.ticks = uint64(C.sysconf(C._SC_CLK_TCK))
system.pagesize = uint64(os.Getpagesize())
}
// utmp can't be used by "encoding/binary" if generated by cgo,
// some pads will be explicitly missing.
type utmp struct {
User [256]uint8
ID [14]uint8
Line [64]uint8
XPad1 int16
Pid int32
Type int16
XPad2 int16
Time int64
Termination int16
Exit int16
Host [256]uint8
XdblWordPad int32
XreservedA [2]int32
XreservedV [6]int32
}
func bootTime() (uint64, error) {
if system.btime != 0 {
return system.btime, nil
}
// Get boot time from /etc/utmp
file, err := os.Open("/etc/utmp")
if err != nil {
return 0, fmt.Errorf("error while opening /etc/utmp: %s", err)
}
defer file.Close()
for {
var utmp utmp
if err := binary.Read(file, binary.BigEndian, &utmp); err != nil {
break
}
if utmp.Type == C.BOOT_TIME {
system.btime = uint64(utmp.Time)
break
}
}
return system.btime, nil
}
func tick2msec(val uint64) uint64 {
return val * 1000 / system.ticks
}
// Get returns the list of file systems
func (self *FileSystemList) Get() error {
var size C.int
_, err := C.mntctl(C.MCTL_QUERY, C.sizeof_int, (*C.char)(unsafe.Pointer(&size)))
if err != nil {
return fmt.Errorf("error while retrieving file system number: %s", err)
}
buf := make([]byte, size)
num, err := C.mntctl(C.MCTL_QUERY, C.ulong(size), (*C.char)(&buf[0]))
if err != nil {
return fmt.Errorf("error while retrieving file system list: %s", err)
}
// Vmount structure has a fixed size area for common data (type,
// offsets, etc) and another area with variable length data (devname,
// options, etc). These data can be accessed based on the offsets
// stored in an array inside the fixed part. They can be retrieve
// using index given by C define.
vmt2data := func(buf []byte, ent *C.struct_vmount, idx int, baseOff int) []byte {
off := int(ent.vmt_data[idx].vmt_off)
size := int(ent.vmt_data[idx].vmt_size)
return buf[baseOff+off : baseOff+off+size]
}
entOff := 0
fslist := make([]FileSystem, num)
for i := 0; i < int(num); i++ {
ent := (*C.struct_vmount)(unsafe.Pointer(&buf[entOff]))
fs := &fslist[i]
// Correspondances taken for /etc/vfs
switch ent.vmt_gfstype {
case C.MNT_AIX:
fs.SysTypeName = "jfs2"
case C.MNT_NAMEFS:
fs.SysTypeName = "namefs"
case C.MNT_NFS:
fs.SysTypeName = "nfs"
case C.MNT_JFS:
fs.SysTypeName = "jfs"
case C.MNT_CDROM:
fs.SysTypeName = "cdrom"
case C.MNT_PROCFS:
fs.SysTypeName = "proc"
case C.MNT_SFS:
fs.SysTypeName = "sfs"
case C.MNT_CACHEFS:
fs.SysTypeName = "cachefs"
case C.MNT_NFS3:
fs.SysTypeName = "nfs3"
case C.MNT_AUTOFS:
fs.SysTypeName = "autofs"
case C.MNT_POOLFS:
fs.SysTypeName = "poolfs"
case C.MNT_UDF:
fs.SysTypeName = "udfs"
case C.MNT_NFS4:
fs.SysTypeName = "nfs4"
case C.MNT_CIFS:
fs.SysTypeName = "cifs"
case C.MNT_PMEMFS:
fs.SysTypeName = "pmemfs"
case C.MNT_AHAFS:
fs.SysTypeName = "ahafs"
case C.MNT_STNFS:
fs.SysTypeName = "stnfs"
default:
if ent.vmt_flags&C.MNT_REMOTE != 0 {
fs.SysTypeName = "network"
} else {
fs.SysTypeName = "none"
}
}
fs.DirName = convertBytesToString(vmt2data(buf, ent, C.VMT_STUB, entOff))
fs.Options = convertBytesToString(vmt2data(buf, ent, C.VMT_ARGS, entOff))
devname := convertBytesToString(vmt2data(buf, ent, C.VMT_OBJECT, entOff))
if ent.vmt_flags&C.MNT_REMOTE != 0 {
hostname := convertBytesToString(vmt2data(buf, ent, C.VMT_OBJECT, entOff))
fs.DevName = hostname + ":" + devname
} else {
fs.DevName = devname
}
entOff += int(ent.vmt_length)
}
self.List = fslist
return nil
}
// Get returns the CPU load average
func (self *LoadAverage) Get() error {
cpudata := C.perfstat_cpu_total_t{}
if _, err := C.perfstat_cpu_total(nil, &cpudata, C.sizeof_perfstat_cpu_total_t, 1); err != nil {
return fmt.Errorf("perfstat_cpu_total: %s", err)
}
// from libperfstat.h:
// "To calculate the load average, divide the numbers by (1<<SBITS).
// SBITS is defined in <sys/proc.h>."
fixedToFloat64 := func(x uint64) float64 {
return float64(x) / (1 << C.SBITS)
}
self.One = fixedToFloat64(uint64(cpudata.loadavg[0]))
self.Five = fixedToFloat64(uint64(cpudata.loadavg[1]))
self.Fifteen = fixedToFloat64(uint64(cpudata.loadavg[2]))
return nil
}
// Get returns the system uptime
func (self *Uptime) Get() error {
btime, err := bootTime()
if err != nil {
return err
}
uptime := time.Now().Sub(time.Unix(int64(btime), 0))
self.Length = uptime.Seconds()
return nil
}
// Get returns the current system memory
func (self *Mem) Get() error {
meminfo := C.perfstat_memory_total_t{}
_, err := C.perfstat_memory_total(nil, &meminfo, C.sizeof_perfstat_memory_total_t, 1)
if err != nil {
return fmt.Errorf("perfstat_memory_total: %s", err)
}
self.Total = uint64(meminfo.real_total) * system.pagesize
self.Free = uint64(meminfo.real_free) * system.pagesize
kern := uint64(meminfo.numperm) * system.pagesize // number of pages in file cache
self.Used = self.Total - self.Free
self.ActualFree = self.Free + kern
self.ActualUsed = self.Used - kern
return nil
}
// Get returns the current system swap memory
func (self *Swap) Get() error {
ps := C.perfstat_pagingspace_t{}
id := C.perfstat_id_t{}
id.name[0] = 0
for {
// errno can be set during perfstat_pagingspace's call even
// if it succeeds. Thus, only check it when the result is -1.
if r, err := C.perfstat_pagingspace(&id, &ps, C.sizeof_perfstat_pagingspace_t, 1); r == -1 && err != nil {
return fmt.Errorf("perfstat_memory_total: %s", err)
}
if ps.active != 1 {
continue
}
// convert MB sizes to bytes
self.Total += uint64(ps.mb_size) * 1024 * 1024
self.Used += uint64(ps.mb_used) * 1024 * 1024
if id.name[0] == 0 {
break
}
}
self.Free = self.Total - self.Used
return nil
}
// Get returns information about a CPU
func (self *Cpu) Get() error {
cpudata := C.perfstat_cpu_total_t{}
if _, err := C.perfstat_cpu_total(nil, &cpudata, C.sizeof_perfstat_cpu_total_t, 1); err != nil {
return fmt.Errorf("perfstat_cpu_total: %s", err)
}
self.User = tick2msec(uint64(cpudata.user))
self.Sys = tick2msec(uint64(cpudata.sys))
self.Idle = tick2msec(uint64(cpudata.idle))
self.Wait = tick2msec(uint64(cpudata.wait))
return nil
}
// Get returns the list of CPU used by the system
func (self *CpuList) Get() error {
cpudata := C.perfstat_cpu_t{}
id := C.perfstat_id_t{}
id.name[0] = 0
// Retrieve the number of cpu using perfstat_cpu
capacity, err := C.perfstat_cpu(nil, nil, C.sizeof_perfstat_cpu_t, 0)
if err != nil {
return fmt.Errorf("error while retrieving CPU number: %s", err)
}
list := make([]Cpu, 0, capacity)
for {
if _, err := C.perfstat_cpu(&id, &cpudata, C.sizeof_perfstat_cpu_t, 1); err != nil {
return fmt.Errorf("perfstat_cpu: %s", err)
}
cpu := Cpu{}
cpu.User = tick2msec(uint64(cpudata.user))
cpu.Sys = tick2msec(uint64(cpudata.sys))
cpu.Idle = tick2msec(uint64(cpudata.idle))
cpu.Wait = tick2msec(uint64(cpudata.wait))
list = append(list, cpu)
if id.name[0] == 0 {
break
}
}
self.List = list
return nil
}
// Get returns the list of all active processes
func (self *ProcList) Get() error {
info := C.struct_procsinfo64{}
pid := C.pid_t(0)
var list []int
for {
// getprocs first argument is a void*
num, err := C.getprocs(unsafe.Pointer(&info), C.sizeof_struct_procsinfo64, nil, 0, &pid, 1)
if err != nil {
return err
}
list = append(list, int(info.pi_pid))
if num == 0 {
break
}
}
self.List = list
return nil
}
// Get returns information about a process
func (self *ProcState) Get(pid int) error {
info := C.struct_procsinfo64{}
cpid := C.pid_t(pid)
num, err := C.getprocs(unsafe.Pointer(&info), C.sizeof_struct_procsinfo64, nil, 0, &cpid, 1)
if err != nil {
return err
}
if num != 1 {
return syscall.ESRCH
}
self.Name = C.GoString(&info.pi_comm[0])
self.Ppid = int(info.pi_ppid)
self.Pgid = int(info.pi_pgrp)
self.Nice = int(info.pi_nice)
self.Tty = int(info.pi_ttyd)
self.Priority = int(info.pi_pri)
switch info.pi_state {
case C.SACTIVE:
self.State = RunStateRun
case C.SIDL:
self.State = RunStateIdle
case C.SSTOP:
self.State = RunStateStop
case C.SZOMB:
self.State = RunStateZombie
case C.SSWAP:
self.State = RunStateSleep
default:
self.State = RunStateUnknown
}
// Get process username. Fallback to UID if username is not available.
uid := strconv.Itoa(int(info.pi_uid))
userID, err := user.LookupId(uid)
if err == nil && userID.Username != "" {
self.Username = userID.Username
} else {
self.Username = uid
}
thrinfo := C.struct_thrdsinfo64{}
tid := C.tid_t(0)
if _, err := C.getthrds(cpid, unsafe.Pointer(&thrinfo), C.sizeof_struct_thrdsinfo64, &tid, 1); err != nil {
self.Processor = int(thrinfo.ti_affinity)
}
return nil
}
//Get returns the current memory usage of a process
func (self *ProcMem) Get(pid int) error {
info := C.struct_procsinfo64{}
cpid := C.pid_t(pid)
num, err := C.getprocs(unsafe.Pointer(&info), C.sizeof_struct_procsinfo64, nil, 0, &cpid, 1)
if err != nil {
return err
}
if num != 1 {
return syscall.ESRCH
}
self.Size = uint64(info.pi_size) * system.pagesize
self.Share = uint64(info.pi_sdsize) * system.pagesize
self.Resident = uint64(info.pi_drss+info.pi_trss) * system.pagesize
self.MinorFaults = uint64(info.pi_minflt)
self.MajorFaults = uint64(info.pi_majflt)
self.PageFaults = self.MinorFaults + self.MajorFaults
return nil
}
// Get returns a process uptime
func (self *ProcTime) Get(pid int) error {
info := C.struct_procsinfo64{}
cpid := C.pid_t(pid)
num, err := C.getprocs(unsafe.Pointer(&info), C.sizeof_struct_procsinfo64, nil, 0, &cpid, 1)
if err != nil {
return err
}
if num != 1 {
return syscall.ESRCH
}
self.StartTime = uint64(info.pi_start) * 1000
self.User = uint64(info.pi_utime) * 1000
self.Sys = uint64(info.pi_stime) * 1000
self.Total = self.User + self.Sys
return nil
}
// Get returns arguments of a process
func (self *ProcArgs) Get(pid int) error {
/* If buffer is not large enough, args are truncated */
buf := make([]byte, 8192)
info := C.struct_procsinfo64{}
info.pi_pid = C.pid_t(pid)
if _, err := C.getargs(unsafe.Pointer(&info), C.sizeof_struct_procsinfo64, (*C.char)(&buf[0]), 8192); err != nil {
return err
}
bbuf := bytes.NewBuffer(buf)
var args []string
for {
arg, err := bbuf.ReadBytes(0)
if err == io.EOF || arg[0] == 0 {
break
}
if err != nil {
return err
}
args = append(args, string(chop(arg)))
}
self.List = args
return nil
}
// Get returns the environment of a process
func (self *ProcEnv) Get(pid int) error {
if self.Vars == nil {
self.Vars = map[string]string{}
}
/* If buffer is not large enough, args are truncated */
buf := make([]byte, 8192)
info := C.struct_procsinfo64{}
info.pi_pid = C.pid_t(pid)
if _, err := C.getevars(unsafe.Pointer(&info), C.sizeof_struct_procsinfo64, (*C.char)(&buf[0]), 8192); err != nil {
return err
}
bbuf := bytes.NewBuffer(buf)
delim := []byte{61} // "="
for {
line, err := bbuf.ReadBytes(0)
if err == io.EOF || line[0] == 0 {
break
}
if err != nil {
return err
}
pair := bytes.SplitN(chop(line), delim, 2)
if len(pair) != 2 {
return fmt.Errorf("Error reading process environment for PID: %d", pid)
}
self.Vars[string(pair[0])] = string(pair[1])
}
return nil
}
// Get returns the path of the process executable
func (self *ProcExe) Get(pid int) error {
/* If buffer is not large enough, args are truncated */
buf := make([]byte, 8192)
info := C.struct_procsinfo64{}
info.pi_pid = C.pid_t(pid)
if _, err := C.getargs(unsafe.Pointer(&info), C.sizeof_struct_procsinfo64, (*C.char)(&buf[0]), 8192); err != nil {
return err
}
bbuf := bytes.NewBuffer(buf)
// retrieve the first argument
cmd, err := bbuf.ReadBytes(0)
if err != nil {
return err
}
self.Name = string(chop(cmd))
cwd, err := os.Readlink("/proc/" + strconv.Itoa(pid) + "/cwd")
if err != nil {
if !os.IsNotExist(err) {
return err
}
}
self.Cwd = cwd
return nil
}
// Get returns process filesystem usage. Not implimented on AIX.
func (*ProcFDUsage) Get(_ int) error {
return ErrNotImplemented{runtime.GOOS}
}
// Get returns filesytem usage. Not implimented on AIX.
func (*FDUsage) Get() error {
return ErrNotImplemented{runtime.GOOS}
}
// Get returns huge pages info. Not implimented on AIX.
func (*HugeTLBPages) Get() error {
return ErrNotImplemented{runtime.GOOS}
}

View File

@ -0,0 +1,501 @@
// Copyright (c) 2012 VMware, Inc.
package gosigar
/*
#include <stdlib.h>
#include <sys/sysctl.h>
#include <sys/mount.h>
#include <mach/mach_init.h>
#include <mach/mach_host.h>
#include <mach/host_info.h>
#include <libproc.h>
#include <mach/processor_info.h>
#include <mach/vm_map.h>
*/
import "C"
import (
"bytes"
"encoding/binary"
"fmt"
"io"
"os/user"
"runtime"
"strconv"
"syscall"
"time"
"unsafe"
)
// Get fetches LoadAverage data
func (self *LoadAverage) Get() error {
avg := []C.double{0, 0, 0}
C.getloadavg(&avg[0], C.int(len(avg)))
self.One = float64(avg[0])
self.Five = float64(avg[1])
self.Fifteen = float64(avg[2])
return nil
}
// Get fetches memory data
func (self *Mem) Get() error {
var vmstat C.vm_statistics_data_t
if err := sysctlbyname("hw.memsize", &self.Total); err != nil {
return err
}
if err := vmInfo(&vmstat); err != nil {
return err
}
kern := uint64(vmstat.inactive_count) << 12
self.Free = uint64(vmstat.free_count) << 12
self.Used = self.Total - self.Free
self.ActualFree = self.Free + kern
self.ActualUsed = self.Used - kern
return nil
}
type xswUsage struct {
Total, Avail, Used uint64
}
// Get fetches swap data
func (self *Swap) Get() error {
swUsage := xswUsage{}
if err := sysctlbyname("vm.swapusage", &swUsage); err != nil {
return err
}
self.Total = swUsage.Total
self.Used = swUsage.Used
self.Free = swUsage.Avail
return nil
}
// Get fetches hugepages data
func (self *HugeTLBPages) Get() error {
return ErrNotImplemented{runtime.GOOS}
}
// Get fetches CPU data
func (self *Cpu) Get() error {
var count C.mach_msg_type_number_t = C.HOST_CPU_LOAD_INFO_COUNT
var cpuload C.host_cpu_load_info_data_t
status := C.host_statistics(C.host_t(C.mach_host_self()),
C.HOST_CPU_LOAD_INFO,
C.host_info_t(unsafe.Pointer(&cpuload)),
&count)
if status != C.KERN_SUCCESS {
return fmt.Errorf("host_statistics error=%d", status)
}
self.User = uint64(cpuload.cpu_ticks[C.CPU_STATE_USER])
self.Sys = uint64(cpuload.cpu_ticks[C.CPU_STATE_SYSTEM])
self.Idle = uint64(cpuload.cpu_ticks[C.CPU_STATE_IDLE])
self.Nice = uint64(cpuload.cpu_ticks[C.CPU_STATE_NICE])
return nil
}
// Get fetches CPU list data
func (self *CpuList) Get() error {
var count C.mach_msg_type_number_t
var cpuload *C.processor_cpu_load_info_data_t
var ncpu C.natural_t
status := C.host_processor_info(C.host_t(C.mach_host_self()),
C.PROCESSOR_CPU_LOAD_INFO,
&ncpu,
(*C.processor_info_array_t)(unsafe.Pointer(&cpuload)),
&count)
if status != C.KERN_SUCCESS {
return fmt.Errorf("host_processor_info error=%d", status)
}
// jump through some cgo casting hoops and ensure we properly free
// the memory that cpuload points to
target := C.vm_map_t(C.mach_task_self_)
address := C.vm_address_t(uintptr(unsafe.Pointer(cpuload)))
defer C.vm_deallocate(target, address, C.vm_size_t(ncpu))
// the body of struct processor_cpu_load_info
// aka processor_cpu_load_info_data_t
var cpuTicks [C.CPU_STATE_MAX]uint32
// copy the cpuload array to a []byte buffer
// where we can binary.Read the data
size := int(ncpu) * binary.Size(cpuTicks)
buf := C.GoBytes(unsafe.Pointer(cpuload), C.int(size))
bbuf := bytes.NewBuffer(buf)
self.List = make([]Cpu, 0, ncpu)
for i := 0; i < int(ncpu); i++ {
cpu := Cpu{}
err := binary.Read(bbuf, binary.LittleEndian, &cpuTicks)
if err != nil {
return err
}
cpu.User = uint64(cpuTicks[C.CPU_STATE_USER])
cpu.Sys = uint64(cpuTicks[C.CPU_STATE_SYSTEM])
cpu.Idle = uint64(cpuTicks[C.CPU_STATE_IDLE])
cpu.Nice = uint64(cpuTicks[C.CPU_STATE_NICE])
self.List = append(self.List, cpu)
}
return nil
}
// Get returns FD usage data
func (self *FDUsage) Get() error {
return ErrNotImplemented{runtime.GOOS}
}
// Get returns filesystem data
func (self *FileSystemList) Get() error {
num, err := syscall.Getfsstat(nil, C.MNT_NOWAIT)
if err != nil {
return err
}
buf := make([]syscall.Statfs_t, num)
_, err = syscall.Getfsstat(buf, C.MNT_NOWAIT)
if err != nil {
return err
}
fslist := make([]FileSystem, 0, num)
for i := 0; i < num; i++ {
fs := FileSystem{}
fs.DirName = byteListToString(buf[i].Mntonname[:])
fs.DevName = byteListToString(buf[i].Mntfromname[:])
fs.SysTypeName = byteListToString(buf[i].Fstypename[:])
fslist = append(fslist, fs)
}
self.List = fslist
return err
}
// Get returns a process list
func (self *ProcList) Get() error {
n := C.proc_listpids(C.PROC_ALL_PIDS, 0, nil, 0)
if n <= 0 {
return syscall.EINVAL
}
buf := make([]byte, n)
n = C.proc_listpids(C.PROC_ALL_PIDS, 0, unsafe.Pointer(&buf[0]), n)
if n <= 0 {
return syscall.ENOMEM
}
var pid int32
num := int(n) / binary.Size(pid)
list := make([]int, 0, num)
bbuf := bytes.NewBuffer(buf)
for i := 0; i < num; i++ {
if err := binary.Read(bbuf, binary.LittleEndian, &pid); err != nil {
return err
}
if pid == 0 {
continue
}
list = append(list, int(pid))
}
self.List = list
return nil
}
// Get returns process state data
func (self *ProcState) Get(pid int) error {
info := C.struct_proc_taskallinfo{}
if err := taskInfo(pid, &info); err != nil {
return err
}
self.Name = C.GoString(&info.pbsd.pbi_comm[0])
switch info.pbsd.pbi_status {
case C.SIDL:
self.State = RunStateIdle
case C.SRUN:
self.State = RunStateRun
case C.SSLEEP:
self.State = RunStateSleep
case C.SSTOP:
self.State = RunStateStop
case C.SZOMB:
self.State = RunStateZombie
default:
self.State = RunStateUnknown
}
self.Ppid = int(info.pbsd.pbi_ppid)
self.Pgid = int(info.pbsd.pbi_pgid)
self.Tty = int(info.pbsd.e_tdev)
self.Priority = int(info.ptinfo.pti_priority)
self.Nice = int(info.pbsd.pbi_nice)
// Get process username. Fallback to UID if username is not available.
uid := strconv.Itoa(int(info.pbsd.pbi_uid))
user, err := user.LookupId(uid)
if err == nil && user.Username != "" {
self.Username = user.Username
} else {
self.Username = uid
}
return nil
}
// Get returns process memory data
func (self *ProcMem) Get(pid int) error {
info := C.struct_proc_taskallinfo{}
if err := taskInfo(pid, &info); err != nil {
return err
}
self.Size = uint64(info.ptinfo.pti_virtual_size)
self.Resident = uint64(info.ptinfo.pti_resident_size)
self.PageFaults = uint64(info.ptinfo.pti_faults)
return nil
}
// Get returns process time data
func (self *ProcTime) Get(pid int) error {
info := C.struct_proc_taskallinfo{}
if err := taskInfo(pid, &info); err != nil {
return err
}
self.User =
uint64(info.ptinfo.pti_total_user) / uint64(time.Millisecond)
self.Sys =
uint64(info.ptinfo.pti_total_system) / uint64(time.Millisecond)
self.Total = self.User + self.Sys
self.StartTime = (uint64(info.pbsd.pbi_start_tvsec) * 1000) +
(uint64(info.pbsd.pbi_start_tvusec) / 1000)
return nil
}
// Get returns process arg data
func (self *ProcArgs) Get(pid int) error {
var args []string
argv := func(arg string) {
args = append(args, arg)
}
err := kernProcargs(pid, nil, argv, nil)
self.List = args
return err
}
// Get returns process environment data
func (self *ProcEnv) Get(pid int) error {
if self.Vars == nil {
self.Vars = map[string]string{}
}
env := func(k, v string) {
self.Vars[k] = v
}
return kernProcargs(pid, nil, nil, env)
}
// Get returns process exec data
func (self *ProcExe) Get(pid int) error {
exe := func(arg string) {
self.Name = arg
}
return kernProcargs(pid, exe, nil, nil)
}
// Get returns process file usage
func (self *ProcFDUsage) Get(pid int) error {
return ErrNotImplemented{runtime.GOOS}
}
// kernProcargs is a wrapper around sysctl KERN_PROCARGS2
// callbacks params are optional,
// up to the caller as to which pieces of data they want
func kernProcargs(pid int,
exe func(string),
argv func(string),
env func(string, string)) error {
mib := []C.int{C.CTL_KERN, C.KERN_PROCARGS2, C.int(pid)}
argmax := uintptr(C.ARG_MAX)
buf := make([]byte, argmax)
err := sysctl(mib, &buf[0], &argmax, nil, 0)
if err != nil {
return nil
}
bbuf := bytes.NewBuffer(buf)
bbuf.Truncate(int(argmax))
var argc int32
binary.Read(bbuf, binary.LittleEndian, &argc)
path, err := bbuf.ReadBytes(0)
if err != nil {
return fmt.Errorf("Error reading the argv[0]: %v", err)
}
if exe != nil {
exe(string(chop(path)))
}
// skip trailing \0's
for {
c, err := bbuf.ReadByte()
if err != nil {
return fmt.Errorf("Error skipping nils: %v", err)
}
if c != 0 {
bbuf.UnreadByte()
break // start of argv[0]
}
}
for i := 0; i < int(argc); i++ {
arg, err := bbuf.ReadBytes(0)
if err == io.EOF {
break
}
if err != nil {
return fmt.Errorf("Error reading args: %v", err)
}
if argv != nil {
argv(string(chop(arg)))
}
}
if env == nil {
return nil
}
delim := []byte{61} // "="
for {
line, err := bbuf.ReadBytes(0)
if err == io.EOF || line[0] == 0 {
break
}
if err != nil {
return fmt.Errorf("Error reading args: %v", err)
}
pair := bytes.SplitN(chop(line), delim, 2)
if len(pair) != 2 {
return fmt.Errorf("Error reading process information for PID: %d", pid)
}
env(string(pair[0]), string(pair[1]))
}
return nil
}
// XXX copied from zsyscall_darwin_amd64.go
func sysctl(mib []C.int, old *byte, oldlen *uintptr,
new *byte, newlen uintptr) (err error) {
var p0 unsafe.Pointer
p0 = unsafe.Pointer(&mib[0])
_, _, e1 := syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(p0),
uintptr(len(mib)),
uintptr(unsafe.Pointer(old)), uintptr(unsafe.Pointer(oldlen)),
uintptr(unsafe.Pointer(new)), uintptr(newlen))
if e1 != 0 {
err = e1
}
return
}
func vmInfo(vmstat *C.vm_statistics_data_t) error {
var count C.mach_msg_type_number_t = C.HOST_VM_INFO_COUNT
status := C.host_statistics(
C.host_t(C.mach_host_self()),
C.HOST_VM_INFO,
C.host_info_t(unsafe.Pointer(vmstat)),
&count)
if status != C.KERN_SUCCESS {
return fmt.Errorf("host_statistics=%d", status)
}
return nil
}
// generic Sysctl buffer unmarshalling
func sysctlbyname(name string, data interface{}) (err error) {
val, err := syscall.Sysctl(name)
if err != nil {
return err
}
buf := []byte(val)
switch v := data.(type) {
case *uint64:
*v = *(*uint64)(unsafe.Pointer(&buf[0]))
return
}
bbuf := bytes.NewBuffer([]byte(val))
return binary.Read(bbuf, binary.LittleEndian, data)
}
func taskInfo(pid int, info *C.struct_proc_taskallinfo) error {
size := C.int(unsafe.Sizeof(*info))
ptr := unsafe.Pointer(info)
n := C.proc_pidinfo(C.int(pid), C.PROC_PIDTASKALLINFO, 0, ptr, size)
if n != size {
return fmt.Errorf("Could not read process info for pid %d", pid)
}
return nil
}

20
vendor/github.com/elastic/gosigar/sigar_darwin.go generated vendored Normal file
View File

@ -0,0 +1,20 @@
// +build !386
package gosigar
import (
"syscall"
"time"
)
func (self *Uptime) Get() error {
tv := syscall.Timeval32{}
if err := sysctlbyname("kern.boottime", &tv); err != nil {
return err
}
self.Length = time.Since(time.Unix(int64(tv.Sec), int64(tv.Usec)*1000)).Seconds()
return nil
}

18
vendor/github.com/elastic/gosigar/sigar_darwin_386.go generated vendored Normal file
View File

@ -0,0 +1,18 @@
package gosigar
import (
"syscall"
"time"
)
func (self *Uptime) Get() error {
tv := syscall.Timeval{}
if err := sysctlbyname("kern.boottime", &tv); err != nil {
return err
}
self.Length = time.Since(time.Unix(int64(tv.Sec), int64(tv.Usec)*1000)).Seconds()
return nil
}

126
vendor/github.com/elastic/gosigar/sigar_format.go generated vendored Normal file
View File

@ -0,0 +1,126 @@
// Copyright (c) 2012 VMware, Inc.
package gosigar
import (
"bufio"
"bytes"
"fmt"
"strconv"
"time"
)
// Go version of apr_strfsize
func FormatSize(size uint64) string {
ord := []string{"K", "M", "G", "T", "P", "E"}
o := 0
buf := new(bytes.Buffer)
w := bufio.NewWriter(buf)
if size < 973 {
fmt.Fprintf(w, "%3d ", size)
w.Flush()
return buf.String()
}
for {
remain := size & 1023
size >>= 10
if size >= 973 {
o++
continue
}
if size < 9 || (size == 9 && remain < 973) {
remain = ((remain * 5) + 256) / 512
if remain >= 10 {
size++
remain = 0
}
fmt.Fprintf(w, "%d.%d%s", size, remain, ord[o])
break
}
if remain >= 512 {
size++
}
fmt.Fprintf(w, "%3d%s", size, ord[o])
break
}
w.Flush()
return buf.String()
}
func FormatPercent(percent float64) string {
return strconv.FormatFloat(percent, 'f', -1, 64) + "%"
}
func (self *FileSystemUsage) UsePercent() float64 {
b_used := (self.Total - self.Free) / 1024
b_avail := self.Avail / 1024
utotal := b_used + b_avail
used := b_used
if utotal != 0 {
u100 := used * 100
pct := u100 / utotal
if u100%utotal != 0 {
pct += 1
}
return (float64(pct) / float64(100)) * 100.0
}
return 0.0
}
func (self *Uptime) Format() string {
buf := new(bytes.Buffer)
w := bufio.NewWriter(buf)
uptime := uint64(self.Length)
days := uptime / (60 * 60 * 24)
if days != 0 {
s := ""
if days > 1 {
s = "s"
}
fmt.Fprintf(w, "%d day%s, ", days, s)
}
minutes := uptime / 60
hours := minutes / 60
hours %= 24
minutes %= 60
fmt.Fprintf(w, "%2d:%02d", hours, minutes)
w.Flush()
return buf.String()
}
func (self *ProcTime) FormatStartTime() string {
if self.StartTime == 0 {
return "00:00"
}
start := time.Unix(int64(self.StartTime)/1000, 0)
format := "Jan02"
if time.Since(start).Seconds() < (60 * 60 * 24) {
format = "15:04"
}
return start.Format(format)
}
func (self *ProcTime) FormatTotal() string {
t := self.Total / 1000
ss := t % 60
t /= 60
mm := t % 60
t /= 60
hh := t % 24
return fmt.Sprintf("%02d:%02d:%02d", hh, mm, ss)
}

158
vendor/github.com/elastic/gosigar/sigar_freebsd.go generated vendored Normal file
View File

@ -0,0 +1,158 @@
// Copied and modified from sigar_linux.go.
package gosigar
import (
"io/ioutil"
"runtime"
"strconv"
"strings"
"unsafe"
)
/*
#include <sys/param.h>
#include <sys/mount.h>
#include <sys/ucred.h>
#include <sys/types.h>
#include <sys/sysctl.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <time.h>
*/
import "C"
func init() {
system.ticks = uint64(C.sysconf(C._SC_CLK_TCK))
Procd = "/compat/linux/proc"
getLinuxBootTime()
}
func getMountTableFileName() string {
return Procd + "/mtab"
}
func (self *Uptime) Get() error {
ts := C.struct_timespec{}
if _, err := C.clock_gettime(C.CLOCK_UPTIME, &ts); err != nil {
return err
}
self.Length = float64(ts.tv_sec) + 1e-9*float64(ts.tv_nsec)
return nil
}
func (self *FDUsage) Get() error {
val := C.uint32_t(0)
sc := C.size_t(4)
name := C.CString("kern.openfiles")
_, err := C.sysctlbyname(name, unsafe.Pointer(&val), &sc, nil, 0)
C.free(unsafe.Pointer(name))
if err != nil {
return err
}
self.Open = uint64(val)
name = C.CString("kern.maxfiles")
_, err = C.sysctlbyname(name, unsafe.Pointer(&val), &sc, nil, 0)
C.free(unsafe.Pointer(name))
if err != nil {
return err
}
self.Max = uint64(val)
self.Unused = self.Max - self.Open
return nil
}
func (self *ProcFDUsage) Get(pid int) error {
err := readFile("/proc/"+strconv.Itoa(pid)+"/rlimit", func(line string) bool {
if strings.HasPrefix(line, "nofile") {
fields := strings.Fields(line)
if len(fields) == 3 {
self.SoftLimit, _ = strconv.ParseUint(fields[1], 10, 64)
self.HardLimit, _ = strconv.ParseUint(fields[2], 10, 64)
}
return false
}
return true
})
if err != nil {
return err
}
// linprocfs only provides this information for this process (self).
fds, err := ioutil.ReadDir(procFileName(pid, "fd"))
if err != nil {
return err
}
self.Open = uint64(len(fds))
return nil
}
func (self *HugeTLBPages) Get() error {
return ErrNotImplemented{runtime.GOOS}
}
func parseCpuStat(self *Cpu, line string) error {
fields := strings.Fields(line)
self.User, _ = strtoull(fields[1])
self.Nice, _ = strtoull(fields[2])
self.Sys, _ = strtoull(fields[3])
self.Idle, _ = strtoull(fields[4])
return nil
}
func (self *Mem) Get() error {
val := C.uint32_t(0)
sc := C.size_t(4)
name := C.CString("vm.stats.vm.v_page_count")
_, err := C.sysctlbyname(name, unsafe.Pointer(&val), &sc, nil, 0)
C.free(unsafe.Pointer(name))
if err != nil {
return err
}
pagecount := uint64(val)
name = C.CString("vm.stats.vm.v_page_size")
_, err = C.sysctlbyname(name, unsafe.Pointer(&val), &sc, nil, 0)
C.free(unsafe.Pointer(name))
if err != nil {
return err
}
pagesize := uint64(val)
name = C.CString("vm.stats.vm.v_free_count")
_, err = C.sysctlbyname(name, unsafe.Pointer(&val), &sc, nil, 0)
C.free(unsafe.Pointer(name))
if err != nil {
return err
}
self.Free = uint64(val) * pagesize
name = C.CString("vm.stats.vm.v_inactive_count")
_, err = C.sysctlbyname(name, unsafe.Pointer(&val), &sc, nil, 0)
C.free(unsafe.Pointer(name))
if err != nil {
return err
}
kern := uint64(val)
self.Total = uint64(pagecount * pagesize)
self.Used = self.Total - self.Free
self.ActualFree = self.Free + (kern * pagesize)
self.ActualUsed = self.Used - (kern * pagesize)
return nil
}

240
vendor/github.com/elastic/gosigar/sigar_interface.go generated vendored Normal file
View File

@ -0,0 +1,240 @@
package gosigar
import (
"time"
)
// ErrNotImplemented is returned when a particular statistic isn't implemented on the host OS.
type ErrNotImplemented struct {
OS string
}
func (e ErrNotImplemented) Error() string {
return "not implemented on " + e.OS
}
// IsNotImplemented returns true if the error is ErrNotImplemented
func IsNotImplemented(err error) bool {
switch err.(type) {
case ErrNotImplemented, *ErrNotImplemented:
return true
default:
return false
}
}
// Sigar is an interface for gathering system host stats
type Sigar interface {
CollectCpuStats(collectionInterval time.Duration) (<-chan Cpu, chan<- struct{})
GetLoadAverage() (LoadAverage, error)
GetMem() (Mem, error)
GetSwap() (Swap, error)
GetHugeTLBPages(HugeTLBPages, error)
GetFileSystemUsage(string) (FileSystemUsage, error)
GetFDUsage() (FDUsage, error)
GetRusage(who int) (Rusage, error)
}
// Cpu contains CPU time stats
type Cpu struct {
User uint64
Nice uint64
Sys uint64
Idle uint64
Wait uint64
Irq uint64
SoftIrq uint64
Stolen uint64
}
// Total returns total CPU time
func (cpu *Cpu) Total() uint64 {
return cpu.User + cpu.Nice + cpu.Sys + cpu.Idle +
cpu.Wait + cpu.Irq + cpu.SoftIrq + cpu.Stolen
}
// Delta returns the difference between two Cpu stat objects
func (cpu Cpu) Delta(other Cpu) Cpu {
return Cpu{
User: cpu.User - other.User,
Nice: cpu.Nice - other.Nice,
Sys: cpu.Sys - other.Sys,
Idle: cpu.Idle - other.Idle,
Wait: cpu.Wait - other.Wait,
Irq: cpu.Irq - other.Irq,
SoftIrq: cpu.SoftIrq - other.SoftIrq,
Stolen: cpu.Stolen - other.Stolen,
}
}
// LoadAverage reports standard load averages
type LoadAverage struct {
One, Five, Fifteen float64
}
// Uptime reports system uptime
type Uptime struct {
Length float64
}
// Mem contains host memory stats
type Mem struct {
Total uint64
Used uint64
Free uint64
Cached uint64
ActualFree uint64
ActualUsed uint64
}
// Swap contains stats on swap space
type Swap struct {
Total uint64
Used uint64
Free uint64
}
// HugeTLBPages contains HugePages stats
type HugeTLBPages struct {
Total uint64
Free uint64
Reserved uint64
Surplus uint64
DefaultSize uint64
TotalAllocatedSize uint64
}
// CpuList contains a list of CPUs on the host system
type CpuList struct {
List []Cpu
}
// FDUsage contains stats on filesystem usage
type FDUsage struct {
Open uint64
Unused uint64
Max uint64
}
// FileSystem contains basic information about a given mounted filesystem
type FileSystem struct {
DirName string
DevName string
TypeName string
SysTypeName string
Options string
Flags uint32
}
// FileSystemList gets a list of mounted filesystems
type FileSystemList struct {
List []FileSystem
}
// FileSystemUsage contains basic stats for the specified filesystem
type FileSystemUsage struct {
Total uint64
Used uint64
Free uint64
Avail uint64
Files uint64
FreeFiles uint64
}
// ProcList contains a list of processes found on the host system
type ProcList struct {
List []int
}
// RunState is a byte-long code used to specify the current runtime state of a process
type RunState byte
const (
// RunStateSleep corresponds to a sleep state
RunStateSleep = 'S'
// RunStateRun corresponds to a running state
RunStateRun = 'R'
// RunStateStop corresponds to a stopped state
RunStateStop = 'T'
// RunStateZombie marks a zombie process
RunStateZombie = 'Z'
// RunStateIdle corresponds to an idle state
RunStateIdle = 'D'
// RunStateUnknown corresponds to a process in an unknown state
RunStateUnknown = '?'
)
// ProcState contains basic metadata and process ownership info for the specified process
type ProcState struct {
Name string
Username string
State RunState
Ppid int
Pgid int
Tty int
Priority int
Nice int
Processor int
}
// ProcMem contains memory statistics for a specified process
type ProcMem struct {
Size uint64
Resident uint64
Share uint64
MinorFaults uint64
MajorFaults uint64
PageFaults uint64
}
// ProcTime contains run time statistics for a specified process
type ProcTime struct {
StartTime uint64
User uint64
Sys uint64
Total uint64
}
// ProcArgs contains a list of args for a specified process
type ProcArgs struct {
List []string
}
// ProcEnv contains a map of environment variables for specified process
type ProcEnv struct {
Vars map[string]string
}
// ProcExe contains basic data about a specified process
type ProcExe struct {
Name string
Cwd string
Root string
}
// ProcFDUsage contains data on file limits and usage
type ProcFDUsage struct {
Open uint64
SoftLimit uint64
HardLimit uint64
}
// Rusage contains data on resource usage for a specified process
type Rusage struct {
Utime time.Duration
Stime time.Duration
Maxrss int64
Ixrss int64
Idrss int64
Isrss int64
Minflt int64
Majflt int64
Nswap int64
Inblock int64
Oublock int64
Msgsnd int64
Msgrcv int64
Nsignals int64
Nvcsw int64
Nivcsw int64
}

138
vendor/github.com/elastic/gosigar/sigar_linux.go generated vendored Normal file
View File

@ -0,0 +1,138 @@
// Copyright (c) 2012 VMware, Inc.
package gosigar
import (
"io/ioutil"
"strconv"
"strings"
"syscall"
)
func init() {
system.ticks = 100 // C.sysconf(C._SC_CLK_TCK)
Procd = "/proc"
getLinuxBootTime()
}
func getMountTableFileName() string {
return "/etc/mtab"
}
// Get returns uptime data
func (self *Uptime) Get() error {
sysinfo := syscall.Sysinfo_t{}
if err := syscall.Sysinfo(&sysinfo); err != nil {
return err
}
self.Length = float64(sysinfo.Uptime)
return nil
}
// Get returns FD usage data
func (self *FDUsage) Get() error {
return readFile(Procd+"/sys/fs/file-nr", func(line string) bool {
fields := strings.Fields(line)
if len(fields) == 3 {
self.Open, _ = strconv.ParseUint(fields[0], 10, 64)
self.Unused, _ = strconv.ParseUint(fields[1], 10, 64)
self.Max, _ = strconv.ParseUint(fields[2], 10, 64)
}
return false
})
}
// Get returns hugepages data
func (self *HugeTLBPages) Get() error {
table, err := parseMeminfo()
if err != nil {
return err
}
self.Total, _ = table["HugePages_Total"]
self.Free, _ = table["HugePages_Free"]
self.Reserved, _ = table["HugePages_Rsvd"]
self.Surplus, _ = table["HugePages_Surp"]
self.DefaultSize, _ = table["Hugepagesize"]
if totalSize, found := table["Hugetlb"]; found {
self.TotalAllocatedSize = totalSize
} else {
// If Hugetlb is not present, or huge pages of different sizes
// are used, this figure can be unaccurate.
// TODO (jsoriano): Extract information from /sys/kernel/mm/hugepages too
self.TotalAllocatedSize = (self.Total - self.Free + self.Reserved) * self.DefaultSize
}
return nil
}
// Get returns process FD usage
func (self *ProcFDUsage) Get(pid int) error {
err := readFile(procFileName(pid, "limits"), func(line string) bool {
if strings.HasPrefix(line, "Max open files") {
fields := strings.Fields(line)
if len(fields) == 6 {
self.SoftLimit, _ = strconv.ParseUint(fields[3], 10, 64)
self.HardLimit, _ = strconv.ParseUint(fields[4], 10, 64)
}
return false
}
return true
})
if err != nil {
return err
}
fds, err := ioutil.ReadDir(procFileName(pid, "fd"))
if err != nil {
return err
}
self.Open = uint64(len(fds))
return nil
}
func parseCpuStat(self *Cpu, line string) error {
fields := strings.Fields(line)
self.User, _ = strtoull(fields[1])
self.Nice, _ = strtoull(fields[2])
self.Sys, _ = strtoull(fields[3])
self.Idle, _ = strtoull(fields[4])
self.Wait, _ = strtoull(fields[5])
self.Irq, _ = strtoull(fields[6])
self.SoftIrq, _ = strtoull(fields[7])
self.Stolen, _ = strtoull(fields[8])
return nil
}
// Get returns memory data
func (self *Mem) Get() error {
table, err := parseMeminfo()
if err != nil {
return err
}
self.Total, _ = table["MemTotal"]
self.Free, _ = table["MemFree"]
buffers, _ := table["Buffers"]
self.Cached, _ = table["Cached"]
if available, ok := table["MemAvailable"]; ok {
// MemAvailable is in /proc/meminfo (kernel 3.14+)
self.ActualFree = available
} else {
self.ActualFree = self.Free + buffers + self.Cached
}
self.Used = self.Total - self.Free
self.ActualUsed = self.Total - self.ActualFree
return nil
}

457
vendor/github.com/elastic/gosigar/sigar_linux_common.go generated vendored Normal file
View File

@ -0,0 +1,457 @@
// Copyright (c) 2012 VMware, Inc.
// +build freebsd linux
package gosigar
import (
"bufio"
"bytes"
"fmt"
"io"
"io/ioutil"
"os"
"os/user"
"path/filepath"
"strconv"
"strings"
"syscall"
)
var system struct {
ticks uint64
btime uint64
}
var Procd string
func getLinuxBootTime() {
// grab system boot time
readFile(Procd+"/stat", func(line string) bool {
if strings.HasPrefix(line, "btime") {
system.btime, _ = strtoull(line[6:])
return false // stop reading
}
return true
})
}
func (self *LoadAverage) Get() error {
line, err := ioutil.ReadFile(Procd + "/loadavg")
if err != nil {
return nil
}
fields := strings.Fields(string(line))
self.One, _ = strconv.ParseFloat(fields[0], 64)
self.Five, _ = strconv.ParseFloat(fields[1], 64)
self.Fifteen, _ = strconv.ParseFloat(fields[2], 64)
return nil
}
func (self *Swap) Get() error {
table, err := parseMeminfo()
if err != nil {
return err
}
self.Total, _ = table["SwapTotal"]
self.Free, _ = table["SwapFree"]
self.Used = self.Total - self.Free
return nil
}
func (self *Cpu) Get() error {
return readFile(Procd+"/stat", func(line string) bool {
if len(line) > 4 && line[0:4] == "cpu " {
parseCpuStat(self, line)
return false
}
return true
})
}
func (self *CpuList) Get() error {
capacity := len(self.List)
if capacity == 0 {
capacity = 4
}
list := make([]Cpu, 0, capacity)
err := readFile(Procd+"/stat", func(line string) bool {
if len(line) > 3 && line[0:3] == "cpu" && line[3] != ' ' {
cpu := Cpu{}
parseCpuStat(&cpu, line)
list = append(list, cpu)
}
return true
})
self.List = list
return err
}
func (self *FileSystemList) Get() error {
capacity := len(self.List)
if capacity == 0 {
capacity = 10
}
fslist := make([]FileSystem, 0, capacity)
err := readFile(getMountTableFileName(), func(line string) bool {
fields := strings.Fields(line)
fs := FileSystem{}
fs.DevName = fields[0]
fs.DirName = fields[1]
fs.SysTypeName = fields[2]
fs.Options = fields[3]
fslist = append(fslist, fs)
return true
})
self.List = fslist
return err
}
func (self *ProcList) Get() error {
dir, err := os.Open(Procd)
if err != nil {
return err
}
defer dir.Close()
const readAllDirnames = -1 // see os.File.Readdirnames doc
names, err := dir.Readdirnames(readAllDirnames)
if err != nil {
return err
}
capacity := len(names)
list := make([]int, 0, capacity)
for _, name := range names {
if name[0] < '0' || name[0] > '9' {
continue
}
pid, err := strconv.Atoi(name)
if err == nil {
list = append(list, pid)
}
}
self.List = list
return nil
}
func (self *ProcState) Get(pid int) error {
data, err := readProcFile(pid, "stat")
if err != nil {
return err
}
// Extract the comm value with is surrounded by parentheses.
lIdx := bytes.Index(data, []byte("("))
rIdx := bytes.LastIndex(data, []byte(")"))
if lIdx < 0 || rIdx < 0 || lIdx >= rIdx || rIdx+2 >= len(data) {
return fmt.Errorf("failed to extract comm for pid %d from '%v'", pid, string(data))
}
self.Name = string(data[lIdx+1 : rIdx])
// Extract the rest of the fields that we are interested in.
fields := bytes.Fields(data[rIdx+2:])
if len(fields) <= 36 {
return fmt.Errorf("expected more stat fields for pid %d from '%v'", pid, string(data))
}
interests := bytes.Join([][]byte{
fields[0], // state
fields[1], // ppid
fields[2], // pgrp
fields[4], // tty_nr
fields[15], // priority
fields[16], // nice
fields[36], // processor (last processor executed on)
}, []byte(" "))
var state string
_, err = fmt.Fscan(bytes.NewBuffer(interests),
&state,
&self.Ppid,
&self.Pgid,
&self.Tty,
&self.Priority,
&self.Nice,
&self.Processor,
)
if err != nil {
return fmt.Errorf("failed to parse stat fields for pid %d from '%v': %v", pid, string(data), err)
}
self.State = RunState(state[0])
// Read /proc/[pid]/status to get the uid, then lookup uid to get username.
status, err := getProcStatus(pid)
if err != nil {
return fmt.Errorf("failed to read process status for pid %d: %v", pid, err)
}
uids, err := getUIDs(status)
if err != nil {
return fmt.Errorf("failed to read process status for pid %d: %v", pid, err)
}
user, err := user.LookupId(uids[0])
if err == nil {
self.Username = user.Username
} else {
self.Username = uids[0]
}
return nil
}
func (self *ProcMem) Get(pid int) error {
contents, err := readProcFile(pid, "statm")
if err != nil {
return err
}
fields := strings.Fields(string(contents))
size, _ := strtoull(fields[0])
self.Size = size << 12
rss, _ := strtoull(fields[1])
self.Resident = rss << 12
share, _ := strtoull(fields[2])
self.Share = share << 12
contents, err = readProcFile(pid, "stat")
if err != nil {
return err
}
fields = strings.Fields(string(contents))
self.MinorFaults, _ = strtoull(fields[10])
self.MajorFaults, _ = strtoull(fields[12])
self.PageFaults = self.MinorFaults + self.MajorFaults
return nil
}
func (self *ProcTime) Get(pid int) error {
contents, err := readProcFile(pid, "stat")
if err != nil {
return err
}
fields := strings.Fields(string(contents))
user, _ := strtoull(fields[13])
sys, _ := strtoull(fields[14])
// convert to millis
self.User = user * (1000 / system.ticks)
self.Sys = sys * (1000 / system.ticks)
self.Total = self.User + self.Sys
// convert to millis
self.StartTime, _ = strtoull(fields[21])
self.StartTime /= system.ticks
self.StartTime += system.btime
self.StartTime *= 1000
return nil
}
func (self *ProcArgs) Get(pid int) error {
contents, err := readProcFile(pid, "cmdline")
if err != nil {
return err
}
bbuf := bytes.NewBuffer(contents)
var args []string
for {
arg, err := bbuf.ReadBytes(0)
if err == io.EOF {
break
}
args = append(args, string(chop(arg)))
}
self.List = args
return nil
}
func (self *ProcEnv) Get(pid int) error {
contents, err := readProcFile(pid, "environ")
if err != nil {
return err
}
if self.Vars == nil {
self.Vars = map[string]string{}
}
pairs := bytes.Split(contents, []byte{0})
for _, kv := range pairs {
parts := bytes.SplitN(kv, []byte{'='}, 2)
if len(parts) != 2 {
continue
}
key := string(bytes.TrimSpace(parts[0]))
if key == "" {
continue
}
self.Vars[key] = string(bytes.TrimSpace(parts[1]))
}
return nil
}
func (self *ProcExe) Get(pid int) error {
fields := map[string]*string{
"exe": &self.Name,
"cwd": &self.Cwd,
"root": &self.Root,
}
for name, field := range fields {
val, err := os.Readlink(procFileName(pid, name))
if err != nil {
return err
}
*field = val
}
return nil
}
func parseMeminfo() (map[string]uint64, error) {
table := map[string]uint64{}
err := readFile(Procd+"/meminfo", func(line string) bool {
fields := strings.Split(line, ":")
if len(fields) != 2 {
return true // skip on errors
}
valueUnit := strings.Fields(fields[1])
value, err := strtoull(valueUnit[0])
if err != nil {
return true // skip on errors
}
if len(valueUnit) > 1 && valueUnit[1] == "kB" {
value *= 1024
}
table[fields[0]] = value
return true
})
return table, err
}
func readFile(file string, handler func(string) bool) error {
contents, err := ioutil.ReadFile(file)
if err != nil {
return err
}
reader := bufio.NewReader(bytes.NewBuffer(contents))
for {
line, _, err := reader.ReadLine()
if err == io.EOF {
break
}
if !handler(string(line)) {
break
}
}
return nil
}
func strtoull(val string) (uint64, error) {
return strconv.ParseUint(val, 10, 64)
}
func procFileName(pid int, name string) string {
return Procd + "/" + strconv.Itoa(pid) + "/" + name
}
func readProcFile(pid int, name string) (content []byte, err error) {
path := procFileName(pid, name)
// Panics have been reported when reading proc files, let's recover and
// report the path if this happens
// See https://github.com/elastic/beats/issues/6692
defer func() {
if r := recover(); r != nil {
content = nil
err = fmt.Errorf("recovered panic when reading proc file '%s': %v", path, r)
}
}()
contents, err := ioutil.ReadFile(path)
if err != nil {
if perr, ok := err.(*os.PathError); ok {
if perr.Err == syscall.ENOENT {
return nil, syscall.ESRCH
}
}
}
return contents, err
}
// getProcStatus reads /proc/[pid]/status which contains process status
// information in human readable form.
func getProcStatus(pid int) (map[string]string, error) {
status := make(map[string]string, 42)
path := filepath.Join(Procd, strconv.Itoa(pid), "status")
err := readFile(path, func(line string) bool {
fields := strings.SplitN(line, ":", 2)
if len(fields) == 2 {
status[fields[0]] = strings.TrimSpace(fields[1])
}
return true
})
return status, err
}
// getUIDs reads the "Uid" value from status and splits it into four values --
// real, effective, saved set, and file system UIDs.
func getUIDs(status map[string]string) ([]string, error) {
uidLine, ok := status["Uid"]
if !ok {
return nil, fmt.Errorf("Uid not found in proc status")
}
uidStrs := strings.Fields(uidLine)
if len(uidStrs) != 4 {
return nil, fmt.Errorf("Uid line ('%s') did not contain four values", uidLine)
}
return uidStrs, nil
}

426
vendor/github.com/elastic/gosigar/sigar_openbsd.go generated vendored Normal file
View File

@ -0,0 +1,426 @@
// Copyright (c) 2016 Jasper Lievisse Adriaanse <j@jasper.la>.
// +build openbsd
package gosigar
/*
#include <sys/param.h>
#include <sys/types.h>
#include <sys/sysctl.h>
#include <sys/mount.h>
#include <sys/sched.h>
#include <sys/swap.h>
#include <stdlib.h>
#include <unistd.h>
*/
import "C"
//import "github.com/davecgh/go-spew/spew"
import (
"runtime"
"syscall"
"time"
"unsafe"
)
type Uvmexp struct {
pagesize uint32
pagemask uint32
pageshift uint32
npages uint32
free uint32
active uint32
inactive uint32
paging uint32
wired uint32
zeropages uint32
reserve_pagedaemon uint32
reserve_kernel uint32
anonpages uint32
vnodepages uint32
vtextpages uint32
freemin uint32
freetarg uint32
inactarg uint32
wiredmax uint32
anonmin uint32
vtextmin uint32
vnodemin uint32
anonminpct uint32
vtextmi uint32
npct uint32
vnodeminpct uint32
nswapdev uint32
swpages uint32
swpginuse uint32
swpgonly uint32
nswget uint32
nanon uint32
nanonneeded uint32
nfreeanon uint32
faults uint32
traps uint32
intrs uint32
swtch uint32
softs uint32
syscalls uint32
pageins uint32
obsolete_swapins uint32
obsolete_swapouts uint32
pgswapin uint32
pgswapout uint32
forks uint32
forks_ppwait uint32
forks_sharevm uint32
pga_zerohit uint32
pga_zeromiss uint32
zeroaborts uint32
fltnoram uint32
fltnoanon uint32
fltpgwait uint32
fltpgrele uint32
fltrelck uint32
fltrelckok uint32
fltanget uint32
fltanretry uint32
fltamcopy uint32
fltnamap uint32
fltnomap uint32
fltlget uint32
fltget uint32
flt_anon uint32
flt_acow uint32
flt_obj uint32
flt_prcopy uint32
flt_przero uint32
pdwoke uint32
pdrevs uint32
pdswout uint32
pdfreed uint32
pdscans uint32
pdanscan uint32
pdobscan uint32
pdreact uint32
pdbusy uint32
pdpageouts uint32
pdpending uint32
pddeact uint32
pdreanon uint32
pdrevnode uint32
pdrevtext uint32
fpswtch uint32
kmapent uint32
}
type Bcachestats struct {
numbufs uint64
numbufpages uint64
numdirtypages uint64
numcleanpages uint64
pendingwrites uint64
pendingreads uint64
numwrites uint64
numreads uint64
cachehits uint64
busymapped uint64
dmapages uint64
highpages uint64
delwribufs uint64
kvaslots uint64
kvaslots_avail uint64
}
type Swapent struct {
se_dev C.dev_t
se_flags int32
se_nblks int32
se_inuse int32
se_priority int32
sw_path []byte
}
func (self *FileSystemList) Get() error {
num, err := syscall.Getfsstat(nil, C.MNT_NOWAIT)
if err != nil {
return err
}
buf := make([]syscall.Statfs_t, num)
_, err = syscall.Getfsstat(buf, C.MNT_NOWAIT)
if err != nil {
return err
}
fslist := make([]FileSystem, 0, num)
for i := 0; i < num; i++ {
fs := FileSystem{}
fs.DirName = byteListToString(buf[i].F_mntonname[:])
fs.DevName = byteListToString(buf[i].F_mntfromname[:])
fs.SysTypeName = byteListToString(buf[i].F_fstypename[:])
fslist = append(fslist, fs)
}
self.List = fslist
return err
}
func (self *FileSystemUsage) Get(path string) error {
stat := syscall.Statfs_t{}
err := syscall.Statfs(path, &stat)
if err != nil {
return err
}
self.Total = uint64(stat.F_blocks) * uint64(stat.F_bsize)
self.Free = uint64(stat.F_bfree) * uint64(stat.F_bsize)
self.Avail = uint64(stat.F_bavail) * uint64(stat.F_bsize)
self.Used = self.Total - self.Free
self.Files = stat.F_files
self.FreeFiles = stat.F_ffree
return nil
}
func (self *FDUsage) Get() error {
return ErrNotImplemented{runtime.GOOS}
}
func (self *LoadAverage) Get() error {
avg := []C.double{0, 0, 0}
C.getloadavg(&avg[0], C.int(len(avg)))
self.One = float64(avg[0])
self.Five = float64(avg[1])
self.Fifteen = float64(avg[2])
return nil
}
func (self *Uptime) Get() error {
tv := syscall.Timeval{}
mib := [2]int32{C.CTL_KERN, C.KERN_BOOTTIME}
n := uintptr(0)
// First we determine how much memory we'll need to pass later on (via `n`)
_, _, errno := syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 2, 0, uintptr(unsafe.Pointer(&n)), 0, 0)
if errno != 0 || n == 0 {
return nil
}
// Now perform the actual sysctl(3) call, storing the result in tv
_, _, errno = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 2, uintptr(unsafe.Pointer(&tv)), uintptr(unsafe.Pointer(&n)), 0, 0)
if errno != 0 || n == 0 {
return nil
}
self.Length = time.Since(time.Unix(int64(tv.Sec), int64(tv.Usec)*1000)).Seconds()
return nil
}
func (self *Mem) Get() error {
n := uintptr(0)
var uvmexp Uvmexp
mib := [2]int32{C.CTL_VM, C.VM_UVMEXP}
n = uintptr(0)
// First we determine how much memory we'll need to pass later on (via `n`)
_, _, errno := syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 2, 0, uintptr(unsafe.Pointer(&n)), 0, 0)
if errno != 0 || n == 0 {
return nil
}
_, _, errno = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 2, uintptr(unsafe.Pointer(&uvmexp)), uintptr(unsafe.Pointer(&n)), 0, 0)
if errno != 0 || n == 0 {
return nil
}
var bcachestats Bcachestats
mib3 := [3]int32{C.CTL_VFS, C.VFS_GENERIC, C.VFS_BCACHESTAT}
n = uintptr(0)
_, _, errno = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib3[0])), 3, 0, uintptr(unsafe.Pointer(&n)), 0, 0)
if errno != 0 || n == 0 {
return nil
}
_, _, errno = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib3[0])), 3, uintptr(unsafe.Pointer(&bcachestats)), uintptr(unsafe.Pointer(&n)), 0, 0)
if errno != 0 || n == 0 {
return nil
}
self.Total = uint64(uvmexp.npages) << uvmexp.pageshift
self.Used = uint64(uvmexp.npages-uvmexp.free) << uvmexp.pageshift
self.Free = uint64(uvmexp.free) << uvmexp.pageshift
self.ActualFree = self.Free + (uint64(bcachestats.numbufpages) << uvmexp.pageshift)
self.ActualUsed = self.Used - (uint64(bcachestats.numbufpages) << uvmexp.pageshift)
return nil
}
func (self *Swap) Get() error {
nswap := C.swapctl(C.SWAP_NSWAP, unsafe.Pointer(uintptr(0)), 0)
// If there are no swap devices, nothing to do here.
if nswap == 0 {
return nil
}
swdev := make([]Swapent, nswap)
rnswap := C.swapctl(C.SWAP_STATS, unsafe.Pointer(&swdev[0]), nswap)
if rnswap == 0 {
return nil
}
for i := 0; i < int(nswap); i++ {
if swdev[i].se_flags&C.SWF_ENABLE == 2 {
self.Used = self.Used + uint64(swdev[i].se_inuse/(1024/C.DEV_BSIZE))
self.Total = self.Total + uint64(swdev[i].se_nblks/(1024/C.DEV_BSIZE))
}
}
self.Free = self.Total - self.Used
return nil
}
func (self *HugeTLBPages) Get() error {
return ErrNotImplemented{runtime.GOOS}
}
func (self *Cpu) Get() error {
load := [C.CPUSTATES]C.long{C.CP_USER, C.CP_NICE, C.CP_SYS, C.CP_INTR, C.CP_IDLE}
mib := [2]int32{C.CTL_KERN, C.KERN_CPTIME}
n := uintptr(0)
// First we determine how much memory we'll need to pass later on (via `n`)
_, _, errno := syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 2, 0, uintptr(unsafe.Pointer(&n)), 0, 0)
if errno != 0 || n == 0 {
return nil
}
_, _, errno = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 2, uintptr(unsafe.Pointer(&load)), uintptr(unsafe.Pointer(&n)), 0, 0)
if errno != 0 || n == 0 {
return nil
}
self.User = uint64(load[0])
self.Nice = uint64(load[1])
self.Sys = uint64(load[2])
self.Irq = uint64(load[3])
self.Idle = uint64(load[4])
return nil
}
func (self *CpuList) Get() error {
mib := [2]int32{C.CTL_HW, C.HW_NCPU}
var ncpu int
n := uintptr(0)
// First we determine how much memory we'll need to pass later on (via `n`)
_, _, errno := syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 2, 0, uintptr(unsafe.Pointer(&n)), 0, 0)
if errno != 0 || n == 0 {
return nil
}
// Now perform the actual sysctl(3) call, storing the result in ncpu
_, _, errno = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 2, uintptr(unsafe.Pointer(&ncpu)), uintptr(unsafe.Pointer(&n)), 0, 0)
if errno != 0 || n == 0 {
return nil
}
load := [C.CPUSTATES]C.long{C.CP_USER, C.CP_NICE, C.CP_SYS, C.CP_INTR, C.CP_IDLE}
self.List = make([]Cpu, ncpu)
for curcpu := range self.List {
sysctlCptime(ncpu, curcpu, &load)
fillCpu(&self.List[curcpu], load)
}
return nil
}
func (self *ProcList) Get() error {
return nil
}
func (self *ProcArgs) Get(pid int) error {
return nil
}
func (self *ProcEnv) Get(pid int) error {
return ErrNotImplemented{runtime.GOOS}
}
func (self *ProcState) Get(pid int) error {
return nil
}
func (self *ProcMem) Get(pid int) error {
return nil
}
func (self *ProcTime) Get(pid int) error {
return ErrNotImplemented{runtime.GOOS}
}
func (self *ProcExe) Get(pid int) error {
return nil
}
func (self *ProcFDUsage) Get(pid int) error {
return ErrNotImplemented{runtime.GOOS}
}
func (self *Rusage) Get(pid int) error {
return ErrNotImplemented{runtime.GOOS}
}
func fillCpu(cpu *Cpu, load [C.CPUSTATES]C.long) {
cpu.User = uint64(load[0])
cpu.Nice = uint64(load[1])
cpu.Sys = uint64(load[2])
cpu.Irq = uint64(load[3])
cpu.Idle = uint64(load[4])
}
func sysctlCptime(ncpu int, curcpu int, load *[C.CPUSTATES]C.long) error {
var mib []int32
// Use the correct mib based on the number of CPUs and fill out the
// current CPU number in case of SMP. (0 indexed cf. self.List)
if ncpu == 0 {
mib = []int32{C.CTL_KERN, C.KERN_CPTIME}
} else {
mib = []int32{C.CTL_KERN, C.KERN_CPTIME2, int32(curcpu)}
}
len := len(mib)
n := uintptr(0)
// First we determine how much memory we'll need to pass later on (via `n`)
_, _, errno := syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), uintptr(len), 0, uintptr(unsafe.Pointer(&n)), 0, 0)
if errno != 0 || n == 0 {
return nil
}
_, _, errno = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), uintptr(len), uintptr(unsafe.Pointer(load)), uintptr(unsafe.Pointer(&n)), 0, 0)
if errno != 0 || n == 0 {
return nil
}
return nil
}

75
vendor/github.com/elastic/gosigar/sigar_stub.go generated vendored Normal file
View File

@ -0,0 +1,75 @@
// +build !aix,!darwin,!freebsd,!linux,!openbsd,!windows
package gosigar
import (
"runtime"
)
func (c *Cpu) Get() error {
return ErrNotImplemented{runtime.GOOS}
}
func (l *LoadAverage) Get() error {
return ErrNotImplemented{runtime.GOOS}
}
func (m *Mem) Get() error {
return ErrNotImplemented{runtime.GOOS}
}
func (s *Swap) Get() error {
return ErrNotImplemented{runtime.GOOS}
}
func (s *HugeTLBPages) Get() error {
return ErrNotImplemented{runtime.GOOS}
}
func (f *FDUsage) Get() error {
return ErrNotImplemented{runtime.GOOS}
}
func (p *ProcTime) Get(int) error {
return ErrNotImplemented{runtime.GOOS}
}
func (self *FileSystemUsage) Get(path string) error {
return ErrNotImplemented{runtime.GOOS}
}
func (self *CpuList) Get() error {
return ErrNotImplemented{runtime.GOOS}
}
func (p *ProcState) Get(int) error {
return ErrNotImplemented{runtime.GOOS}
}
func (p *ProcExe) Get(int) error {
return ErrNotImplemented{runtime.GOOS}
}
func (p *ProcMem) Get(int) error {
return ErrNotImplemented{runtime.GOOS}
}
func (p *ProcFDUsage) Get(int) error {
return ErrNotImplemented{runtime.GOOS}
}
func (p *ProcEnv) Get(int) error {
return ErrNotImplemented{runtime.GOOS}
}
func (p *ProcList) Get() error {
return ErrNotImplemented{runtime.GOOS}
}
func (p *ProcArgs) Get(int) error {
return ErrNotImplemented{runtime.GOOS}
}
func (self *Rusage) Get(int) error {
return ErrNotImplemented{runtime.GOOS}
}

69
vendor/github.com/elastic/gosigar/sigar_unix.go generated vendored Normal file
View File

@ -0,0 +1,69 @@
// Copyright (c) 2012 VMware, Inc.
// +build aix darwin freebsd linux
package gosigar
import (
"syscall"
"time"
"golang.org/x/sys/unix"
)
func (self *FileSystemUsage) Get(path string) error {
stat := syscall.Statfs_t{}
err := syscall.Statfs(path, &stat)
if err != nil {
return err
}
self.Total = uint64(stat.Blocks) * uint64(stat.Bsize)
self.Free = uint64(stat.Bfree) * uint64(stat.Bsize)
self.Avail = uint64(stat.Bavail) * uint64(stat.Bsize)
self.Used = self.Total - self.Free
self.Files = stat.Files
self.FreeFiles = uint64(stat.Ffree)
return nil
}
func (r *Rusage) Get(who int) error {
ru, err := getResourceUsage(who)
if err != nil {
return err
}
uTime := convertRtimeToDur(ru.Utime)
sTime := convertRtimeToDur(ru.Stime)
r.Utime = uTime
r.Stime = sTime
r.Maxrss = int64(ru.Maxrss)
r.Ixrss = int64(ru.Ixrss)
r.Idrss = int64(ru.Idrss)
r.Isrss = int64(ru.Isrss)
r.Minflt = int64(ru.Minflt)
r.Majflt = int64(ru.Majflt)
r.Nswap = int64(ru.Nswap)
r.Inblock = int64(ru.Inblock)
r.Oublock = int64(ru.Oublock)
r.Msgsnd = int64(ru.Msgsnd)
r.Msgrcv = int64(ru.Msgrcv)
r.Nsignals = int64(ru.Nsignals)
r.Nvcsw = int64(ru.Nvcsw)
r.Nivcsw = int64(ru.Nivcsw)
return nil
}
func getResourceUsage(who int) (unix.Rusage, error) {
r := unix.Rusage{}
err := unix.Getrusage(who, &r)
return r, err
}
func convertRtimeToDur(t unix.Timeval) time.Duration {
return time.Duration(t.Nano())
}

30
vendor/github.com/elastic/gosigar/sigar_util.go generated vendored Normal file
View File

@ -0,0 +1,30 @@
// Copyright (c) 2012 VMware, Inc.
package gosigar
import (
"bytes"
)
// byteListToString converts the raw byte arrays we get into a string. This is a bit of a process, as byte strings are normally []uint8
func byteListToString(raw []int8) string {
byteList := make([]byte, len(raw))
for pos, singleByte := range raw {
byteList[pos] = byte(singleByte)
if singleByte == 0 {
break
}
}
return string(bytes.Trim(byteList, "\x00"))
}
func chop(buf []byte) []byte {
return buf[0 : len(buf)-1]
}
// convertBytesToString trims null bytes and returns a string
func convertBytesToString(arr []byte) string {
return string(bytes.Trim(arr, "\x00"))
}

401
vendor/github.com/elastic/gosigar/sigar_windows.go generated vendored Normal file
View File

@ -0,0 +1,401 @@
// Copyright (c) 2012 VMware, Inc.
package gosigar
import (
"fmt"
"os"
"path/filepath"
"runtime"
"strings"
"syscall"
"time"
"github.com/elastic/gosigar/sys/windows"
"github.com/pkg/errors"
)
var (
// version is Windows version of the host OS.
version = windows.GetWindowsVersion()
// processQueryLimitedInfoAccess is set to PROCESS_QUERY_INFORMATION for Windows
// 2003 and XP where PROCESS_QUERY_LIMITED_INFORMATION is unknown. For all newer
// OS versions it is set to PROCESS_QUERY_LIMITED_INFORMATION.
processQueryLimitedInfoAccess = windows.PROCESS_QUERY_LIMITED_INFORMATION
)
func init() {
if !version.IsWindowsVistaOrGreater() {
// PROCESS_QUERY_LIMITED_INFORMATION cannot be used on 2003 or XP.
processQueryLimitedInfoAccess = syscall.PROCESS_QUERY_INFORMATION
}
}
func (self *LoadAverage) Get() error {
return ErrNotImplemented{runtime.GOOS}
}
func (self *FDUsage) Get() error {
return ErrNotImplemented{runtime.GOOS}
}
func (self *ProcEnv) Get(pid int) error {
return ErrNotImplemented{runtime.GOOS}
}
func (self *ProcExe) Get(pid int) error {
return ErrNotImplemented{runtime.GOOS}
}
func (self *ProcFDUsage) Get(pid int) error {
return ErrNotImplemented{runtime.GOOS}
}
func (self *Uptime) Get() error {
// Minimum supported OS is Windows Vista.
if !version.IsWindowsVistaOrGreater() {
return ErrNotImplemented{runtime.GOOS}
}
uptimeMs, err := windows.GetTickCount64()
if err != nil {
return errors.Wrap(err, "failed to get boot time using GetTickCount64 api")
}
self.Length = float64(time.Duration(uptimeMs)*time.Millisecond) / float64(time.Second)
return nil
}
func (self *Mem) Get() error {
memoryStatusEx, err := windows.GlobalMemoryStatusEx()
if err != nil {
return errors.Wrap(err, "GlobalMemoryStatusEx failed")
}
self.Total = memoryStatusEx.TotalPhys
self.Free = memoryStatusEx.AvailPhys
self.Used = self.Total - self.Free
self.ActualFree = self.Free
self.ActualUsed = self.Used
return nil
}
func (self *Swap) Get() error {
memoryStatusEx, err := windows.GlobalMemoryStatusEx()
if err != nil {
return errors.Wrap(err, "GlobalMemoryStatusEx failed")
}
self.Total = memoryStatusEx.TotalPageFile
self.Free = memoryStatusEx.AvailPageFile
self.Used = self.Total - self.Free
return nil
}
func (self *HugeTLBPages) Get() error {
return ErrNotImplemented{runtime.GOOS}
}
func (self *Cpu) Get() error {
idle, kernel, user, err := windows.GetSystemTimes()
if err != nil {
return errors.Wrap(err, "GetSystemTimes failed")
}
// CPU times are reported in milliseconds by gosigar.
self.Idle = uint64(idle / time.Millisecond)
self.Sys = uint64(kernel / time.Millisecond)
self.User = uint64(user / time.Millisecond)
return nil
}
func (self *CpuList) Get() error {
cpus, err := windows.NtQuerySystemProcessorPerformanceInformation()
if err != nil {
return errors.Wrap(err, "NtQuerySystemProcessorPerformanceInformation failed")
}
self.List = make([]Cpu, 0, len(cpus))
for _, cpu := range cpus {
self.List = append(self.List, Cpu{
Idle: uint64(cpu.IdleTime / time.Millisecond),
Sys: uint64(cpu.KernelTime / time.Millisecond),
User: uint64(cpu.UserTime / time.Millisecond),
})
}
return nil
}
func (self *FileSystemList) Get() error {
drives, err := windows.GetAccessPaths()
if err != nil {
return errors.Wrap(err, "GetAccessPaths failed")
}
for _, drive := range drives {
dt, err := windows.GetDriveType(drive)
if err != nil {
return errors.Wrapf(err, "GetDriveType failed")
}
fsType, err := windows.GetFilesystemType(drive)
if err != nil {
return errors.Wrapf(err, "GetFilesystemType failed")
}
if fsType != "" {
self.List = append(self.List, FileSystem{
DirName: drive,
DevName: drive,
TypeName: dt.String(),
SysTypeName: fsType,
})
}
}
return nil
}
// Get retrieves a list of all process identifiers (PIDs) in the system.
func (self *ProcList) Get() error {
pids, err := windows.EnumProcesses()
if err != nil {
return errors.Wrap(err, "EnumProcesses failed")
}
// Convert uint32 PIDs to int.
self.List = make([]int, 0, len(pids))
for _, pid := range pids {
self.List = append(self.List, int(pid))
}
return nil
}
func (self *ProcState) Get(pid int) error {
var errs []error
var err error
self.Name, err = getProcName(pid)
if err != nil {
errs = append(errs, errors.Wrap(err, "getProcName failed"))
}
self.State, err = getProcStatus(pid)
if err != nil {
errs = append(errs, errors.Wrap(err, "getProcStatus failed"))
}
self.Ppid, err = getParentPid(pid)
if err != nil {
errs = append(errs, errors.Wrap(err, "getParentPid failed"))
}
// getProcCredName will often fail when run as a non-admin user. This is
// caused by strict ACL of the process token belonging to other users.
// Instead of failing completely, ignore this error and still return most
// data with an empty Username.
self.Username, _ = getProcCredName(pid)
if len(errs) > 0 {
errStrs := make([]string, 0, len(errs))
for _, e := range errs {
errStrs = append(errStrs, e.Error())
}
return errors.New(strings.Join(errStrs, "; "))
}
return nil
}
// getProcName returns the process name associated with the PID.
func getProcName(pid int) (string, error) {
handle, err := syscall.OpenProcess(processQueryLimitedInfoAccess, false, uint32(pid))
if err != nil {
return "", errors.Wrapf(err, "OpenProcess failed for pid=%v", pid)
}
defer syscall.CloseHandle(handle)
filename, err := windows.GetProcessImageFileName(handle)
if err != nil {
return "", errors.Wrapf(err, "GetProcessImageFileName failed for pid=%v", pid)
}
return filepath.Base(filename), nil
}
// getProcStatus returns the status of a process.
func getProcStatus(pid int) (RunState, error) {
handle, err := syscall.OpenProcess(processQueryLimitedInfoAccess, false, uint32(pid))
if err != nil {
return RunStateUnknown, errors.Wrapf(err, "OpenProcess failed for pid=%v", pid)
}
defer syscall.CloseHandle(handle)
var exitCode uint32
err = syscall.GetExitCodeProcess(handle, &exitCode)
if err != nil {
return RunStateUnknown, errors.Wrapf(err, "GetExitCodeProcess failed for pid=%v", pid)
}
if exitCode == 259 { //still active
return RunStateRun, nil
}
return RunStateSleep, nil
}
// getParentPid returns the parent process ID of a process.
func getParentPid(pid int) (int, error) {
handle, err := syscall.OpenProcess(processQueryLimitedInfoAccess, false, uint32(pid))
if err != nil {
return RunStateUnknown, errors.Wrapf(err, "OpenProcess failed for pid=%v", pid)
}
defer syscall.CloseHandle(handle)
procInfo, err := windows.NtQueryProcessBasicInformation(handle)
if err != nil {
return 0, errors.Wrapf(err, "NtQueryProcessBasicInformation failed for pid=%v", pid)
}
return int(procInfo.InheritedFromUniqueProcessID), nil
}
func getProcCredName(pid int) (string, error) {
handle, err := syscall.OpenProcess(syscall.PROCESS_QUERY_INFORMATION, false, uint32(pid))
if err != nil {
return "", errors.Wrapf(err, "OpenProcess failed for pid=%v", pid)
}
defer syscall.CloseHandle(handle)
// Find process token via win32.
var token syscall.Token
err = syscall.OpenProcessToken(handle, syscall.TOKEN_QUERY, &token)
if err != nil {
return "", errors.Wrapf(err, "OpenProcessToken failed for pid=%v", pid)
}
// Close token to prevent handle leaks.
defer token.Close()
// Find the token user.
tokenUser, err := token.GetTokenUser()
if err != nil {
return "", errors.Wrapf(err, "GetTokenInformation failed for pid=%v", pid)
}
// Look up domain account by SID.
account, domain, _, err := tokenUser.User.Sid.LookupAccount("")
if err != nil {
sid, sidErr := tokenUser.User.Sid.String()
if sidErr != nil {
return "", errors.Wrapf(err, "failed while looking up account name for pid=%v", pid)
}
return "", errors.Wrapf(err, "failed while looking up account name for SID=%v of pid=%v", sid, pid)
}
return fmt.Sprintf(`%s\%s`, domain, account), nil
}
func (self *ProcMem) Get(pid int) error {
handle, err := syscall.OpenProcess(processQueryLimitedInfoAccess|windows.PROCESS_VM_READ, false, uint32(pid))
if err != nil {
return errors.Wrapf(err, "OpenProcess failed for pid=%v", pid)
}
defer syscall.CloseHandle(handle)
counters, err := windows.GetProcessMemoryInfo(handle)
if err != nil {
return errors.Wrapf(err, "GetProcessMemoryInfo failed for pid=%v", pid)
}
self.Resident = uint64(counters.WorkingSetSize)
self.Size = uint64(counters.PrivateUsage)
return nil
}
func (self *ProcTime) Get(pid int) error {
cpu, err := getProcTimes(pid)
if err != nil {
return err
}
// Windows epoch times are expressed as time elapsed since midnight on
// January 1, 1601 at Greenwich, England. This converts the Filetime to
// unix epoch in milliseconds.
self.StartTime = uint64(cpu.CreationTime.Nanoseconds() / 1e6)
// Convert to millis.
self.User = uint64(windows.FiletimeToDuration(&cpu.UserTime).Nanoseconds() / 1e6)
self.Sys = uint64(windows.FiletimeToDuration(&cpu.KernelTime).Nanoseconds() / 1e6)
self.Total = self.User + self.Sys
return nil
}
func getProcTimes(pid int) (*syscall.Rusage, error) {
handle, err := syscall.OpenProcess(processQueryLimitedInfoAccess, false, uint32(pid))
if err != nil {
return nil, errors.Wrapf(err, "OpenProcess failed for pid=%v", pid)
}
defer syscall.CloseHandle(handle)
var cpu syscall.Rusage
if err := syscall.GetProcessTimes(handle, &cpu.CreationTime, &cpu.ExitTime, &cpu.KernelTime, &cpu.UserTime); err != nil {
return nil, errors.Wrapf(err, "GetProcessTimes failed for pid=%v", pid)
}
return &cpu, nil
}
func (self *ProcArgs) Get(pid int) error {
// The minimum supported client for Win32_Process is Windows Vista.
if !version.IsWindowsVistaOrGreater() {
return ErrNotImplemented{runtime.GOOS}
}
handle, err := syscall.OpenProcess(processQueryLimitedInfoAccess|windows.PROCESS_VM_READ, false, uint32(pid))
if err != nil {
return errors.Wrapf(err, "OpenProcess failed for pid=%v", pid)
}
defer syscall.CloseHandle(handle)
pbi, err := windows.NtQueryProcessBasicInformation(handle)
if err != nil {
return errors.Wrapf(err, "NtQueryProcessBasicInformation failed for pid=%v", pid)
}
if err != nil {
return nil
}
userProcParams, err := windows.GetUserProcessParams(handle, pbi)
if err != nil {
return nil
}
if argsW, err := windows.ReadProcessUnicodeString(handle, &userProcParams.CommandLine); err == nil {
self.List, err = windows.ByteSliceToStringSlice(argsW)
if err != nil {
return err
}
}
return nil
}
func (self *FileSystemUsage) Get(path string) error {
freeBytesAvailable, totalNumberOfBytes, totalNumberOfFreeBytes, err := windows.GetDiskFreeSpaceEx(path)
if err != nil {
return errors.Wrap(err, "GetDiskFreeSpaceEx failed")
}
self.Total = totalNumberOfBytes
self.Free = totalNumberOfFreeBytes
self.Used = self.Total - self.Free
self.Avail = freeBytesAvailable
return nil
}
func (self *Rusage) Get(who int) error {
if who != 0 {
return ErrNotImplemented{runtime.GOOS}
}
pid := os.Getpid()
cpu, err := getProcTimes(pid)
if err != nil {
return err
}
self.Utime = windows.FiletimeToDuration(&cpu.UserTime)
self.Stime = windows.FiletimeToDuration(&cpu.KernelTime)
return nil
}

8
vendor/github.com/elastic/gosigar/sys/windows/doc.go generated vendored Normal file
View File

@ -0,0 +1,8 @@
// Package windows contains various Windows system call.
package windows
// Use "go generate -v -x ." to generate the source.
// Add -trace to enable debug prints around syscalls.
//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -systemdll=true -output zsyscall_windows.go syscall_windows.go
//go:generate go run fix_generated.go -input zsyscall_windows.go

View File

@ -0,0 +1,132 @@
// +build windows
package windows
import (
"bytes"
"encoding/binary"
"io"
"runtime"
"syscall"
"time"
"unsafe"
"github.com/pkg/errors"
)
// On both 32-bit and 64-bit systems NtQuerySystemInformation expects the
// size of SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION to be 48.
const sizeofSystemProcessorPerformanceInformation = 48
// ProcessBasicInformation is an equivalent representation of
// PROCESS_BASIC_INFORMATION in the Windows API.
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms684280(v=vs.85).aspx
type ProcessBasicInformation struct {
ExitStatus uint
PebBaseAddress uintptr
AffinityMask uint
BasePriority uint
UniqueProcessID uint
InheritedFromUniqueProcessID uint
}
// NtQueryProcessBasicInformation queries basic information about the process
// associated with the given handle (provided by OpenProcess). It uses the
// NtQueryInformationProcess function to collect the data.
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms684280(v=vs.85).aspx
func NtQueryProcessBasicInformation(handle syscall.Handle) (ProcessBasicInformation, error) {
var processBasicInfo ProcessBasicInformation
processBasicInfoPtr := (*byte)(unsafe.Pointer(&processBasicInfo))
size := uint32(unsafe.Sizeof(processBasicInfo))
ntStatus, _ := _NtQueryInformationProcess(handle, 0, processBasicInfoPtr, size, nil)
if ntStatus != 0 {
return ProcessBasicInformation{}, errors.Errorf("NtQueryInformationProcess failed, NTSTATUS=0x%X", ntStatus)
}
return processBasicInfo, nil
}
// SystemProcessorPerformanceInformation contains CPU performance information
// for a single CPU.
type SystemProcessorPerformanceInformation struct {
IdleTime time.Duration // Amount of time spent idle.
KernelTime time.Duration // Kernel time does NOT include time spent in idle.
UserTime time.Duration // Amount of time spent executing in user mode.
}
// _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION is an equivalent representation of
// SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION in the Windows API. This struct is
// used internally with NtQuerySystemInformation call and is not exported. The
// exported equivalent is SystemProcessorPerformanceInformation.
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724509(v=vs.85).aspx
type _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION struct {
IdleTime int64
KernelTime int64
UserTime int64
Reserved1 [2]int64
Reserved2 uint32
}
// NtQuerySystemProcessorPerformanceInformation queries CPU performance
// information for each CPU. It uses the NtQuerySystemInformation function to
// collect the SystemProcessorPerformanceInformation.
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724509(v=vs.85).aspx
func NtQuerySystemProcessorPerformanceInformation() ([]SystemProcessorPerformanceInformation, error) {
// NTSTATUS code for success.
// https://msdn.microsoft.com/en-us/library/cc704588.aspx
const STATUS_SUCCESS = 0
// From the _SYSTEM_INFORMATION_CLASS enum.
// http://processhacker.sourceforge.net/doc/ntexapi_8h.html#ad5d815b48e8f4da1ef2eb7a2f18a54e0
const systemProcessorPerformanceInformation = 8
// Create a buffer large enough to hold an entry for each processor.
b := make([]byte, runtime.NumCPU()*sizeofSystemProcessorPerformanceInformation)
// Query the performance information. Note that this function uses 0 to
// indicate success. Most other Windows functions use non-zero for success.
var returnLength uint32
ntStatus, _ := _NtQuerySystemInformation(systemProcessorPerformanceInformation, &b[0], uint32(len(b)), &returnLength)
if ntStatus != STATUS_SUCCESS {
return nil, errors.Errorf("NtQuerySystemInformation failed, NTSTATUS=0x%X, bufLength=%v, returnLength=%v", ntStatus, len(b), returnLength)
}
return readSystemProcessorPerformanceInformationBuffer(b)
}
// readSystemProcessorPerformanceInformationBuffer reads from a buffer
// containing SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION data. The buffer should
// contain one entry for each CPU.
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724509(v=vs.85).aspx
func readSystemProcessorPerformanceInformationBuffer(b []byte) ([]SystemProcessorPerformanceInformation, error) {
n := len(b) / sizeofSystemProcessorPerformanceInformation
r := bytes.NewReader(b)
rtn := make([]SystemProcessorPerformanceInformation, 0, n)
for i := 0; i < n; i++ {
_, err := r.Seek(int64(i*sizeofSystemProcessorPerformanceInformation), io.SeekStart)
if err != nil {
return nil, errors.Wrapf(err, "failed to seek to cpuN=%v in buffer", i)
}
times := make([]uint64, 3)
for j := range times {
err := binary.Read(r, binary.LittleEndian, &times[j])
if err != nil {
return nil, errors.Wrapf(err, "failed reading cpu times for cpuN=%v", i)
}
}
idleTime := time.Duration(times[0] * 100)
kernelTime := time.Duration(times[1] * 100)
userTime := time.Duration(times[2] * 100)
rtn = append(rtn, SystemProcessorPerformanceInformation{
IdleTime: idleTime,
KernelTime: kernelTime - idleTime, // Subtract out idle time from kernel time.
UserTime: userTime,
})
}
return rtn, nil
}

View File

@ -0,0 +1,272 @@
// +build windows
package windows
import (
"bytes"
"encoding/binary"
"encoding/json"
"fmt"
"runtime"
"strings"
"sync"
"syscall"
"github.com/pkg/errors"
"golang.org/x/sys/windows"
)
// Cache of privilege names to LUIDs.
var (
privNames = make(map[string]int64)
privNameMutex sync.Mutex
)
const (
// SeDebugPrivilege is the name of the privilege used to debug programs.
SeDebugPrivilege = "SeDebugPrivilege"
)
// Errors returned by AdjustTokenPrivileges.
const (
ERROR_NOT_ALL_ASSIGNED syscall.Errno = 1300
)
// Attribute bits for privileges.
const (
_SE_PRIVILEGE_ENABLED_BY_DEFAULT uint32 = 0x00000001
_SE_PRIVILEGE_ENABLED uint32 = 0x00000002
_SE_PRIVILEGE_REMOVED uint32 = 0x00000004
_SE_PRIVILEGE_USED_FOR_ACCESS uint32 = 0x80000000
)
// Privilege contains information about a single privilege associated with a
// Token.
type Privilege struct {
LUID int64 `json:"-"` // Locally unique identifier (guaranteed only until the system is restarted).
Name string `json:"-"`
EnabledByDefault bool `json:"enabled_by_default,omitempty"`
Enabled bool `json:"enabled"`
Removed bool `json:"removed,omitempty"`
Used bool `json:"used,omitempty"`
}
func (p Privilege) String() string {
var buf bytes.Buffer
buf.WriteString(p.Name)
buf.WriteString("=(")
opts := make([]string, 0, 4)
if p.EnabledByDefault {
opts = append(opts, "Default")
}
if p.Enabled {
opts = append(opts, "Enabled")
}
if !p.EnabledByDefault && !p.Enabled {
opts = append(opts, "Disabled")
}
if p.Removed {
opts = append(opts, "Removed")
}
if p.Used {
opts = append(opts, "Used")
}
buf.WriteString(strings.Join(opts, ", "))
buf.WriteString(")")
// Example: SeDebugPrivilege=(Default, Enabled)
return buf.String()
}
// User represent the information about a Windows account.
type User struct {
SID string
Account string
Domain string
Type uint32
}
func (u User) String() string {
return fmt.Sprintf(`User:%v\%v, SID:%v, Type:%v`, u.Domain, u.Account, u.SID, u.Type)
}
// DebugInfo contains general debug info about the current process.
type DebugInfo struct {
OSVersion Version // OS version info.
Arch string // Architecture of the machine.
NumCPU int // Number of CPUs.
User User // User that this process is running as.
ProcessPrivs map[string]Privilege // Privileges held by the process.
}
func (d DebugInfo) String() string {
bytes, _ := json.Marshal(d)
return string(bytes)
}
// LookupPrivilegeName looks up a privilege name given a LUID value.
func LookupPrivilegeName(systemName string, luid int64) (string, error) {
buf := make([]uint16, 256)
bufSize := uint32(len(buf))
err := _LookupPrivilegeName(systemName, &luid, &buf[0], &bufSize)
if err != nil {
return "", errors.Wrapf(err, "LookupPrivilegeName failed for luid=%v", luid)
}
return syscall.UTF16ToString(buf), nil
}
// mapPrivileges maps privilege names to LUID values.
func mapPrivileges(names []string) ([]int64, error) {
var privileges []int64
privNameMutex.Lock()
defer privNameMutex.Unlock()
for _, name := range names {
p, ok := privNames[name]
if !ok {
err := _LookupPrivilegeValue("", name, &p)
if err != nil {
return nil, errors.Wrapf(err, "LookupPrivilegeValue failed on '%v'", name)
}
privNames[name] = p
}
privileges = append(privileges, p)
}
return privileges, nil
}
// EnableTokenPrivileges enables the specified privileges in the given
// Token. The token must have TOKEN_ADJUST_PRIVILEGES access. If the token
// does not already contain the privilege it cannot be enabled.
func EnableTokenPrivileges(token syscall.Token, privileges ...string) error {
privValues, err := mapPrivileges(privileges)
if err != nil {
return err
}
var b bytes.Buffer
binary.Write(&b, binary.LittleEndian, uint32(len(privValues)))
for _, p := range privValues {
binary.Write(&b, binary.LittleEndian, p)
binary.Write(&b, binary.LittleEndian, uint32(_SE_PRIVILEGE_ENABLED))
}
success, err := _AdjustTokenPrivileges(token, false, &b.Bytes()[0], uint32(b.Len()), nil, nil)
if !success {
return err
}
if err == ERROR_NOT_ALL_ASSIGNED {
return errors.Wrap(err, "error not all privileges were assigned")
}
return nil
}
// GetTokenPrivileges returns a list of privileges associated with a token.
// The provided token must have at a minimum TOKEN_QUERY access. This is a
// wrapper around the GetTokenInformation function.
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa446671(v=vs.85).aspx
func GetTokenPrivileges(token syscall.Token) (map[string]Privilege, error) {
// Determine the required buffer size.
var size uint32
syscall.GetTokenInformation(token, syscall.TokenPrivileges, nil, 0, &size)
// This buffer will receive a TOKEN_PRIVILEGE structure.
b := bytes.NewBuffer(make([]byte, size))
err := syscall.GetTokenInformation(token, syscall.TokenPrivileges, &b.Bytes()[0], uint32(b.Len()), &size)
if err != nil {
return nil, errors.Wrap(err, "GetTokenInformation failed")
}
var privilegeCount uint32
err = binary.Read(b, binary.LittleEndian, &privilegeCount)
if err != nil {
return nil, errors.Wrap(err, "failed to read PrivilegeCount")
}
rtn := make(map[string]Privilege, privilegeCount)
for i := 0; i < int(privilegeCount); i++ {
var luid int64
err = binary.Read(b, binary.LittleEndian, &luid)
if err != nil {
return nil, errors.Wrap(err, "failed to read LUID value")
}
var attributes uint32
err = binary.Read(b, binary.LittleEndian, &attributes)
if err != nil {
return nil, errors.Wrap(err, "failed to read attributes")
}
name, err := LookupPrivilegeName("", luid)
if err != nil {
return nil, errors.Wrapf(err, "LookupPrivilegeName failed for LUID=%v", luid)
}
rtn[name] = Privilege{
LUID: luid,
Name: name,
EnabledByDefault: (attributes & _SE_PRIVILEGE_ENABLED_BY_DEFAULT) > 0,
Enabled: (attributes & _SE_PRIVILEGE_ENABLED) > 0,
Removed: (attributes & _SE_PRIVILEGE_REMOVED) > 0,
Used: (attributes & _SE_PRIVILEGE_USED_FOR_ACCESS) > 0,
}
}
return rtn, nil
}
// GetTokenUser returns the User associated with the given Token.
func GetTokenUser(token syscall.Token) (User, error) {
tokenUser, err := token.GetTokenUser()
if err != nil {
return User{}, errors.Wrap(err, "GetTokenUser failed")
}
var user User
user.SID, err = tokenUser.User.Sid.String()
if err != nil {
return user, errors.Wrap(err, "ConvertSidToStringSid failed")
}
user.Account, user.Domain, user.Type, err = tokenUser.User.Sid.LookupAccount("")
if err != nil {
return user, errors.Wrap(err, "LookupAccountSid failed")
}
return user, nil
}
// GetDebugInfo returns general debug info about the current process.
func GetDebugInfo() (*DebugInfo, error) {
h, err := windows.GetCurrentProcess()
if err != nil {
return nil, err
}
var token syscall.Token
err = syscall.OpenProcessToken(syscall.Handle(h), syscall.TOKEN_QUERY, &token)
if err != nil {
return nil, err
}
privs, err := GetTokenPrivileges(token)
if err != nil {
return nil, err
}
user, err := GetTokenUser(token)
if err != nil {
return nil, err
}
return &DebugInfo{
User: user,
ProcessPrivs: privs,
OSVersion: GetWindowsVersion(),
Arch: runtime.GOARCH,
NumCPU: runtime.NumCPU(),
}, nil
}

View File

@ -0,0 +1,634 @@
package windows
import (
"fmt"
"strings"
"syscall"
"time"
"unsafe"
"github.com/pkg/errors"
)
var (
sizeofUint32 = 4
sizeofProcessEntry32 = uint32(unsafe.Sizeof(ProcessEntry32{}))
sizeofProcessMemoryCountersEx = uint32(unsafe.Sizeof(ProcessMemoryCountersEx{}))
sizeofMemoryStatusEx = uint32(unsafe.Sizeof(MemoryStatusEx{}))
)
// Process-specific access rights. Others are declared in the syscall package.
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms684880(v=vs.85).aspx
const (
PROCESS_QUERY_LIMITED_INFORMATION uint32 = 0x1000
PROCESS_VM_READ uint32 = 0x0010
)
// error codes for GetVolumeInformation function
const (
ERROR_INVALID_FUNCTION syscall.Errno = 1
ERROR_NOT_READY syscall.Errno = 21
)
// SizeOfRtlUserProcessParameters gives the size
// of the RtlUserProcessParameters struct.
const SizeOfRtlUserProcessParameters = unsafe.Sizeof(RtlUserProcessParameters{})
// MAX_PATH is the maximum length for a path in Windows.
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx
const MAX_PATH = 260
// DriveType represents a type of drive (removable, fixed, CD-ROM, RAM disk, or
// network drive).
type DriveType uint32
// Drive types as returned by GetDriveType.
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa364939(v=vs.85).aspx
const (
DRIVE_UNKNOWN DriveType = iota
DRIVE_NO_ROOT_DIR
DRIVE_REMOVABLE
DRIVE_FIXED
DRIVE_REMOTE
DRIVE_CDROM
DRIVE_RAMDISK
)
// UnicodeString is Go's equivalent for the _UNICODE_STRING struct.
type UnicodeString struct {
Size uint16
MaximumLength uint16
Buffer uintptr
}
// RtlUserProcessParameters is Go's equivalent for the
// _RTL_USER_PROCESS_PARAMETERS struct.
// A few undocumented fields are exposed.
type RtlUserProcessParameters struct {
Reserved1 [16]byte
Reserved2 [5]uintptr
CurrentDirectoryPath UnicodeString
CurrentDirectoryHandle uintptr
DllPath UnicodeString
ImagePathName UnicodeString
CommandLine UnicodeString
}
func (dt DriveType) String() string {
names := map[DriveType]string{
DRIVE_UNKNOWN: "unknown",
DRIVE_NO_ROOT_DIR: "invalid",
DRIVE_REMOVABLE: "removable",
DRIVE_FIXED: "fixed",
DRIVE_REMOTE: "remote",
DRIVE_CDROM: "cdrom",
DRIVE_RAMDISK: "ramdisk",
}
name, found := names[dt]
if !found {
return "unknown DriveType value"
}
return name
}
// Flags that can be used with CreateToolhelp32Snapshot.
const (
TH32CS_INHERIT uint32 = 0x80000000 // Indicates that the snapshot handle is to be inheritable.
TH32CS_SNAPHEAPLIST uint32 = 0x00000001 // Includes all heaps of the process specified in th32ProcessID in the snapshot.
TH32CS_SNAPMODULE uint32 = 0x00000008 // Includes all modules of the process specified in th32ProcessID in the snapshot.
TH32CS_SNAPMODULE32 uint32 = 0x00000010 // Includes all 32-bit modules of the process specified in th32ProcessID in the snapshot when called from a 64-bit process.
TH32CS_SNAPPROCESS uint32 = 0x00000002 // Includes all processes in the system in the snapshot.
TH32CS_SNAPTHREAD uint32 = 0x00000004 // Includes all threads in the system in the snapshot.
)
// ProcessEntry32 is an equivalent representation of PROCESSENTRY32 in the
// Windows API. It contains a process's information. Do not modify or reorder.
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms684839(v=vs.85).aspx
type ProcessEntry32 struct {
size uint32
CntUsage uint32
ProcessID uint32
DefaultHeapID uintptr
ModuleID uint32
CntThreads uint32
ParentProcessID uint32
PriorityClassBase int32
Flags uint32
exeFile [MAX_PATH]uint16
}
// ExeFile returns the name of the executable file for the process. It does
// not contain the full path.
func (p ProcessEntry32) ExeFile() string {
return syscall.UTF16ToString(p.exeFile[:])
}
func (p ProcessEntry32) String() string {
return fmt.Sprintf("{CntUsage:%v ProcessID:%v DefaultHeapID:%v ModuleID:%v "+
"CntThreads:%v ParentProcessID:%v PriorityClassBase:%v Flags:%v ExeFile:%v",
p.CntUsage, p.ProcessID, p.DefaultHeapID, p.ModuleID, p.CntThreads,
p.ParentProcessID, p.PriorityClassBase, p.Flags, p.ExeFile())
}
// MemoryStatusEx is an equivalent representation of MEMORYSTATUSEX in the
// Windows API. It contains information about the current state of both physical
// and virtual memory, including extended memory.
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa366770
type MemoryStatusEx struct {
length uint32
MemoryLoad uint32
TotalPhys uint64
AvailPhys uint64
TotalPageFile uint64
AvailPageFile uint64
TotalVirtual uint64
AvailVirtual uint64
AvailExtendedVirtual uint64
}
// ProcessMemoryCountersEx is an equivalent representation of
// PROCESS_MEMORY_COUNTERS_EX in the Windows API.
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms684874(v=vs.85).aspx
type ProcessMemoryCountersEx struct {
cb uint32
PageFaultCount uint32
PeakWorkingSetSize uintptr
WorkingSetSize uintptr
QuotaPeakPagedPoolUsage uintptr
QuotaPagedPoolUsage uintptr
QuotaPeakNonPagedPoolUsage uintptr
QuotaNonPagedPoolUsage uintptr
PagefileUsage uintptr
PeakPagefileUsage uintptr
PrivateUsage uintptr
}
// GetLogicalDriveStrings returns a list of drives in the system.
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa364975(v=vs.85).aspx
func GetLogicalDriveStrings() ([]string, error) {
// Determine the size of the buffer required to receive all drives.
bufferLength, err := _GetLogicalDriveStringsW(0, nil)
if err != nil {
return nil, errors.Wrap(err, "GetLogicalDriveStringsW failed to get buffer length")
}
if bufferLength < 0 {
return nil, errors.New("GetLogicalDriveStringsW returned an invalid buffer length")
}
buffer := make([]uint16, bufferLength)
_, err = _GetLogicalDriveStringsW(uint32(len(buffer)), &buffer[0])
if err != nil {
return nil, errors.Wrap(err, "GetLogicalDriveStringsW failed")
}
return UTF16SliceToStringSlice(buffer), nil
}
// GetAccessPaths returns the list of access paths for volumes in the system.
func GetAccessPaths() ([]string, error) {
volumes, err := GetVolumes()
if err != nil {
return nil, errors.Wrap(err, "GetVolumes failed")
}
var paths []string
for _, volumeName := range volumes {
volumePaths, err := GetVolumePathsForVolume(volumeName)
if err != nil {
return nil, errors.Wrapf(err, "failed to get list of access paths for volume '%s'", volumeName)
}
if len(volumePaths) == 0 {
continue
}
// Get only the first path
paths = append(paths, volumePaths[0])
}
return paths, nil
}
// GetVolumes returs the list of volumes in the system.
// https://docs.microsoft.com/es-es/windows/desktop/api/fileapi/nf-fileapi-findfirstvolumew
func GetVolumes() ([]string, error) {
buffer := make([]uint16, MAX_PATH+1)
var volumes []string
h, err := _FindFirstVolume(&buffer[0], uint32(len(buffer)))
if err != nil {
return nil, errors.Wrap(err, "FindFirstVolumeW failed")
}
defer _FindVolumeClose(h)
for {
volumes = append(volumes, syscall.UTF16ToString(buffer))
err = _FindNextVolume(h, &buffer[0], uint32(len(buffer)))
if err != nil {
if errors.Cause(err) == syscall.ERROR_NO_MORE_FILES {
break
}
return nil, errors.Wrap(err, "FindNextVolumeW failed")
}
}
return volumes, nil
}
// GetVolumePathsForVolume returns the list of volume paths for a volume.
// https://docs.microsoft.com/en-us/windows/desktop/api/FileAPI/nf-fileapi-getvolumepathnamesforvolumenamew
func GetVolumePathsForVolume(volumeName string) ([]string, error) {
var length uint32
err := _GetVolumePathNamesForVolumeName(volumeName, nil, 0, &length)
if errors.Cause(err) != syscall.ERROR_MORE_DATA {
return nil, errors.Wrap(err, "GetVolumePathNamesForVolumeNameW failed to get needed buffer length")
}
if length == 0 {
// Not mounted, no paths, that's ok
return nil, nil
}
buffer := make([]uint16, length*(MAX_PATH+1))
err = _GetVolumePathNamesForVolumeName(volumeName, &buffer[0], length, &length)
if err != nil {
return nil, errors.Wrap(err, "GetVolumePathNamesForVolumeNameW failed")
}
return UTF16SliceToStringSlice(buffer), nil
}
// GlobalMemoryStatusEx retrieves information about the system's current usage
// of both physical and virtual memory.
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa366589(v=vs.85).aspx
func GlobalMemoryStatusEx() (MemoryStatusEx, error) {
memoryStatusEx := MemoryStatusEx{length: sizeofMemoryStatusEx}
err := _GlobalMemoryStatusEx(&memoryStatusEx)
if err != nil {
return MemoryStatusEx{}, errors.Wrap(err, "GlobalMemoryStatusEx failed")
}
return memoryStatusEx, nil
}
// GetProcessMemoryInfo retrieves information about the memory usage of the
// specified process.
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms683219(v=vs.85).aspx
func GetProcessMemoryInfo(handle syscall.Handle) (ProcessMemoryCountersEx, error) {
processMemoryCountersEx := ProcessMemoryCountersEx{cb: sizeofProcessMemoryCountersEx}
err := _GetProcessMemoryInfo(handle, &processMemoryCountersEx, processMemoryCountersEx.cb)
if err != nil {
return ProcessMemoryCountersEx{}, errors.Wrap(err, "GetProcessMemoryInfo failed")
}
return processMemoryCountersEx, nil
}
// GetProcessImageFileName Retrieves the name of the executable file for the
// specified process.
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms683217(v=vs.85).aspx
func GetProcessImageFileName(handle syscall.Handle) (string, error) {
buffer := make([]uint16, MAX_PATH)
_, err := _GetProcessImageFileName(handle, &buffer[0], uint32(len(buffer)))
if err != nil {
return "", errors.Wrap(err, "GetProcessImageFileName failed")
}
return syscall.UTF16ToString(buffer), nil
}
// GetSystemTimes retrieves system timing information. On a multiprocessor
// system, the values returned are the sum of the designated times across all
// processors. The returned kernel time does not include the system idle time.
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724400(v=vs.85).aspx
func GetSystemTimes() (idle, kernel, user time.Duration, err error) {
var idleTime, kernelTime, userTime syscall.Filetime
err = _GetSystemTimes(&idleTime, &kernelTime, &userTime)
if err != nil {
return 0, 0, 0, errors.Wrap(err, "GetSystemTimes failed")
}
idle = FiletimeToDuration(&idleTime)
kernel = FiletimeToDuration(&kernelTime) // Kernel time includes idle time so we subtract it out.
user = FiletimeToDuration(&userTime)
return idle, kernel - idle, user, nil
}
// FiletimeToDuration converts a Filetime to a time.Duration. Do not use this
// method to convert a Filetime to an actual clock time, for that use
// Filetime.Nanosecond().
func FiletimeToDuration(ft *syscall.Filetime) time.Duration {
n := int64(ft.HighDateTime)<<32 + int64(ft.LowDateTime) // in 100-nanosecond intervals
return time.Duration(n * 100)
}
// GetDriveType Determines whether a disk drive is a removable, fixed, CD-ROM,
// RAM disk, or network drive. A trailing backslash is required on the
// rootPathName.
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa364939
func GetDriveType(rootPathName string) (DriveType, error) {
rootPathNamePtr, err := syscall.UTF16PtrFromString(rootPathName)
if err != nil {
return DRIVE_UNKNOWN, errors.Wrapf(err, "UTF16PtrFromString failed for rootPathName=%v", rootPathName)
}
dt, err := _GetDriveType(rootPathNamePtr)
if err != nil {
return DRIVE_UNKNOWN, errors.Wrapf(err, "GetDriveType failed for rootPathName=%v", rootPathName)
}
return dt, nil
}
// GetFilesystemType returns file system type information at the given root path.
// https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getvolumeinformationw
func GetFilesystemType(rootPathName string) (string, error) {
rootPathNamePtr, err := syscall.UTF16PtrFromString(rootPathName)
if err != nil {
return "", errors.Wrapf(err, "UTF16PtrFromString failed for rootPathName=%v", rootPathName)
}
buffer := make([]uint16, MAX_PATH+1)
success, err := _GetVolumeInformation(rootPathNamePtr, nil, 0, nil, nil, nil, &buffer[0], MAX_PATH)
// check if CD-ROM or other type that is not supported in GetVolumeInformation function
if err == ERROR_NOT_READY || err == ERROR_INVALID_FUNCTION {
return "", nil
}
if !success {
return "", errors.Wrap(err, "GetVolumeInformationW failed")
}
return strings.ToLower(syscall.UTF16ToString(buffer)), nil
}
// EnumProcesses retrieves the process identifier for each process object in the
// system. This function can return a max of 65536 PIDs. If there are more
// processes than that then this will not return them all.
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms682629(v=vs.85).aspx
func EnumProcesses() ([]uint32, error) {
enumProcesses := func(size int) ([]uint32, error) {
var (
pids = make([]uint32, size)
sizeBytes = len(pids) * sizeofUint32
bytesWritten uint32
)
err := _EnumProcesses(&pids[0], uint32(sizeBytes), &bytesWritten)
pidsWritten := int(bytesWritten) / sizeofUint32
if int(bytesWritten)%sizeofUint32 != 0 || pidsWritten > len(pids) {
return nil, errors.Errorf("EnumProcesses returned an invalid bytesWritten value of %v", bytesWritten)
}
pids = pids[:pidsWritten]
return pids, err
}
// Retry the EnumProcesses call with larger arrays if needed.
size := 2048
var pids []uint32
for tries := 0; tries < 5; tries++ {
var err error
pids, err = enumProcesses(size)
if err != nil {
return nil, errors.Wrap(err, "EnumProcesses failed")
}
if len(pids) < size {
break
}
// Increase the size the pids array and retry the enumProcesses call
// because the array wasn't large enough to hold all of the processes.
size *= 2
}
return pids, nil
}
// GetDiskFreeSpaceEx retrieves information about the amount of space that is
// available on a disk volume, which is the total amount of space, the total
// amount of free space, and the total amount of free space available to the
// user that is associated with the calling thread.
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa364937(v=vs.85).aspx
func GetDiskFreeSpaceEx(directoryName string) (freeBytesAvailable, totalNumberOfBytes, totalNumberOfFreeBytes uint64, err error) {
directoryNamePtr, err := syscall.UTF16PtrFromString(directoryName)
if err != nil {
return 0, 0, 0, errors.Wrapf(err, "UTF16PtrFromString failed for directoryName=%v", directoryName)
}
err = _GetDiskFreeSpaceEx(directoryNamePtr, &freeBytesAvailable, &totalNumberOfBytes, &totalNumberOfFreeBytes)
if err != nil {
return 0, 0, 0, err
}
return freeBytesAvailable, totalNumberOfBytes, totalNumberOfFreeBytes, nil
}
// CreateToolhelp32Snapshot takes a snapshot of the specified processes, as well
// as the heaps, modules, and threads used by these processes.
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms682489(v=vs.85).aspx
func CreateToolhelp32Snapshot(flags, pid uint32) (syscall.Handle, error) {
h, err := _CreateToolhelp32Snapshot(flags, pid)
if err != nil {
return syscall.InvalidHandle, err
}
if h == syscall.InvalidHandle {
return syscall.InvalidHandle, syscall.GetLastError()
}
return h, nil
}
// Process32First retrieves information about the first process encountered in a
// system snapshot.
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms684834
func Process32First(handle syscall.Handle) (ProcessEntry32, error) {
processEntry32 := ProcessEntry32{size: sizeofProcessEntry32}
err := _Process32First(handle, &processEntry32)
if err != nil {
return ProcessEntry32{}, errors.Wrap(err, "Process32First failed")
}
return processEntry32, nil
}
// Process32Next retrieves information about the next process recorded in a
// system snapshot. When there are no more processes to iterate then
// syscall.ERROR_NO_MORE_FILES is returned (use errors.Cause() to unwrap).
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms684836
func Process32Next(handle syscall.Handle) (ProcessEntry32, error) {
processEntry32 := ProcessEntry32{size: sizeofProcessEntry32}
err := _Process32Next(handle, &processEntry32)
if err != nil {
return ProcessEntry32{}, errors.Wrap(err, "Process32Next failed")
}
return processEntry32, nil
}
// UTF16SliceToStringSlice converts slice of uint16 containing a list of UTF16
// strings to a slice of strings.
func UTF16SliceToStringSlice(buffer []uint16) []string {
// Split the uint16 slice at null-terminators.
var startIdx int
var stringsUTF16 [][]uint16
for i, value := range buffer {
if value == 0 {
stringsUTF16 = append(stringsUTF16, buffer[startIdx:i])
startIdx = i + 1
}
}
// Convert the utf16 slices to strings.
result := make([]string, 0, len(stringsUTF16))
for _, stringUTF16 := range stringsUTF16 {
if len(stringUTF16) > 0 {
result = append(result, syscall.UTF16ToString(stringUTF16))
}
}
return result
}
func GetUserProcessParams(handle syscall.Handle, pbi ProcessBasicInformation) (params RtlUserProcessParameters, err error) {
const is32bitProc = unsafe.Sizeof(uintptr(0)) == 4
// Offset of params field within PEB structure.
// This structure is different in 32 and 64 bit.
paramsOffset := 0x20
if is32bitProc {
paramsOffset = 0x10
}
// Read the PEB from the target process memory
pebSize := paramsOffset + 8
peb := make([]byte, pebSize)
nRead, err := ReadProcessMemory(handle, pbi.PebBaseAddress, peb)
if err != nil {
return params, err
}
if nRead != uintptr(pebSize) {
return params, errors.Errorf("PEB: short read (%d/%d)", nRead, pebSize)
}
// Get the RTL_USER_PROCESS_PARAMETERS struct pointer from the PEB
paramsAddr := *(*uintptr)(unsafe.Pointer(&peb[paramsOffset]))
// Read the RTL_USER_PROCESS_PARAMETERS from the target process memory
paramsBuf := make([]byte, SizeOfRtlUserProcessParameters)
nRead, err = ReadProcessMemory(handle, paramsAddr, paramsBuf)
if err != nil {
return params, err
}
if nRead != uintptr(SizeOfRtlUserProcessParameters) {
return params, errors.Errorf("RTL_USER_PROCESS_PARAMETERS: short read (%d/%d)", nRead, SizeOfRtlUserProcessParameters)
}
params = *(*RtlUserProcessParameters)(unsafe.Pointer(&paramsBuf[0]))
return params, nil
}
// ReadProcessUnicodeString returns a zero-terminated UTF-16 string from another
// process's memory.
func ReadProcessUnicodeString(handle syscall.Handle, s *UnicodeString) ([]byte, error) {
// Allocate an extra UTF-16 null character at the end in case the read string
// is not terminated.
extra := 2
if s.Size&1 != 0 {
extra = 3 // If size is odd, need 3 nulls to terminate.
}
buf := make([]byte, int(s.Size)+extra)
nRead, err := ReadProcessMemory(handle, s.Buffer, buf[:s.Size])
if err != nil {
return nil, err
}
if nRead != uintptr(s.Size) {
return nil, errors.Errorf("unicode string: short read: (%d/%d)", nRead, s.Size)
}
return buf, nil
}
// ByteSliceToStringSlice uses CommandLineToArgv API to split an UTF-16 command
// line string into a list of parameters.
func ByteSliceToStringSlice(utf16 []byte) ([]string, error) {
n := len(utf16)
// Discard odd byte
if n&1 != 0 {
n--
utf16 = utf16[:n]
}
if n == 0 {
return nil, nil
}
terminated := false
for i := 0; i < n && !terminated; i += 2 {
terminated = utf16[i] == 0 && utf16[i+1] == 0
}
if !terminated {
// Append a null uint16 at the end if terminator is missing
utf16 = append(utf16, 0, 0)
}
var numArgs int32
argsWide, err := syscall.CommandLineToArgv((*uint16)(unsafe.Pointer(&utf16[0])), &numArgs)
if err != nil {
return nil, err
}
// Free memory allocated for CommandLineToArgvW arguments.
defer syscall.LocalFree((syscall.Handle)(unsafe.Pointer(argsWide)))
args := make([]string, numArgs)
for idx := range args {
args[idx] = syscall.UTF16ToString(argsWide[idx][:])
}
return args, nil
}
// ReadProcessMemory reads from another process memory. The Handle needs to have
// the PROCESS_VM_READ right.
// A zero-byte read is a no-op, no error is returned.
func ReadProcessMemory(handle syscall.Handle, baseAddress uintptr, dest []byte) (numRead uintptr, err error) {
n := len(dest)
if n == 0 {
return 0, nil
}
if err = _ReadProcessMemory(handle, baseAddress, uintptr(unsafe.Pointer(&dest[0])), uintptr(n), &numRead); err != nil {
return 0, err
}
return numRead, nil
}
func GetTickCount64() (uptime uint64, err error) {
if uptime, err = _GetTickCount64(); err != nil {
return 0, err
}
return uptime, nil
}
// Windows API calls
//sys _GlobalMemoryStatusEx(buffer *MemoryStatusEx) (err error) = kernel32.GlobalMemoryStatusEx
//sys _GetLogicalDriveStringsW(bufferLength uint32, buffer *uint16) (length uint32, err error) = kernel32.GetLogicalDriveStringsW
//sys _GetProcessMemoryInfo(handle syscall.Handle, psmemCounters *ProcessMemoryCountersEx, cb uint32) (err error) = psapi.GetProcessMemoryInfo
//sys _GetProcessImageFileName(handle syscall.Handle, outImageFileName *uint16, size uint32) (length uint32, err error) = psapi.GetProcessImageFileNameW
//sys _GetSystemTimes(idleTime *syscall.Filetime, kernelTime *syscall.Filetime, userTime *syscall.Filetime) (err error) = kernel32.GetSystemTimes
//sys _GetDriveType(rootPathName *uint16) (dt DriveType, err error) = kernel32.GetDriveTypeW
//sys _GetVolumeInformation(rootPathName *uint16, volumeName *uint16, volumeNameSize uint32, volumeSerialNumber *uint32, maximumComponentLength *uint32, fileSystemFlags *uint32, fileSystemName *uint16, fileSystemNameSize uint32) (success bool, err error) [true] = kernel32.GetVolumeInformationW
//sys _EnumProcesses(processIds *uint32, sizeBytes uint32, bytesReturned *uint32) (err error) = psapi.EnumProcesses
//sys _GetDiskFreeSpaceEx(directoryName *uint16, freeBytesAvailable *uint64, totalNumberOfBytes *uint64, totalNumberOfFreeBytes *uint64) (err error) = kernel32.GetDiskFreeSpaceExW
//sys _Process32First(handle syscall.Handle, processEntry32 *ProcessEntry32) (err error) = kernel32.Process32FirstW
//sys _Process32Next(handle syscall.Handle, processEntry32 *ProcessEntry32) (err error) = kernel32.Process32NextW
//sys _CreateToolhelp32Snapshot(flags uint32, processID uint32) (handle syscall.Handle, err error) = kernel32.CreateToolhelp32Snapshot
//sys _NtQuerySystemInformation(systemInformationClass uint32, systemInformation *byte, systemInformationLength uint32, returnLength *uint32) (ntstatus uint32, err error) = ntdll.NtQuerySystemInformation
//sys _NtQueryInformationProcess(processHandle syscall.Handle, processInformationClass uint32, processInformation *byte, processInformationLength uint32, returnLength *uint32) (ntstatus uint32, err error) = ntdll.NtQueryInformationProcess
//sys _LookupPrivilegeName(systemName string, luid *int64, buffer *uint16, size *uint32) (err error) = advapi32.LookupPrivilegeNameW
//sys _LookupPrivilegeValue(systemName string, name string, luid *int64) (err error) = advapi32.LookupPrivilegeValueW
//sys _AdjustTokenPrivileges(token syscall.Token, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) [true] = advapi32.AdjustTokenPrivileges
//sys _FindFirstVolume(volumeName *uint16, size uint32) (handle syscall.Handle, err error) = kernel32.FindFirstVolumeW
//sys _FindNextVolume(handle syscall.Handle, volumeName *uint16, size uint32) (err error) = kernel32.FindNextVolumeW
//sys _FindVolumeClose(handle syscall.Handle) (err error) = kernel32.FindVolumeClose
//sys _GetVolumePathNamesForVolumeName(volumeName string, buffer *uint16, bufferSize uint32, length *uint32) (err error) = kernel32.GetVolumePathNamesForVolumeNameW
//sys _ReadProcessMemory(handle syscall.Handle, baseAddress uintptr, buffer uintptr, size uintptr, numRead *uintptr) (err error) = kernel32.ReadProcessMemory
//sys _GetTickCount64() (uptime uint64, err error) = kernel32.GetTickCount64

View File

@ -0,0 +1,43 @@
// +build windows
package windows
import (
"fmt"
"syscall"
)
// Version identifies a Windows version by major, minor, and build number.
type Version struct {
Major int
Minor int
Build int
}
// GetWindowsVersion returns the Windows version information. Applications not
// manifested for Windows 8.1 or Windows 10 will return the Windows 8 OS version
// value (6.2).
//
// For a table of version numbers see:
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724833(v=vs.85).aspx
func GetWindowsVersion() Version {
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724439(v=vs.85).aspx
ver, err := syscall.GetVersion()
if err != nil {
// GetVersion should never return an error.
panic(fmt.Errorf("GetVersion failed: %v", err))
}
return Version{
Major: int(ver & 0xFF),
Minor: int(ver >> 8 & 0xFF),
Build: int(ver >> 16),
}
}
// IsWindowsVistaOrGreater returns true if the Windows version is Vista or
// greater.
func (v Version) IsWindowsVistaOrGreater() bool {
// Vista is 6.0.
return v.Major >= 6 && v.Minor >= 0
}

View File

@ -0,0 +1,299 @@
// Code generated by 'go generate'; DO NOT EDIT.
package windows
import (
"syscall"
"unsafe"
"golang.org/x/sys/windows"
)
var _ unsafe.Pointer
// Do the interface allocations only once for common
// Errno values.
const (
errnoERROR_IO_PENDING = 997
)
var (
errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
errERROR_EINVAL error = syscall.EINVAL
)
// errnoErr returns common boxed Errno values, to prevent
// allocations at runtime.
func errnoErr(e syscall.Errno) error {
switch e {
case 0:
return errERROR_EINVAL
case errnoERROR_IO_PENDING:
return errERROR_IO_PENDING
}
// TODO: add more here, after collecting data on the common
// error values see on Windows. (perhaps when running
// all.bat?)
return e
}
var (
modadvapi32 = windows.NewLazySystemDLL("advapi32.dll")
modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
modntdll = windows.NewLazySystemDLL("ntdll.dll")
modpsapi = windows.NewLazySystemDLL("psapi.dll")
procAdjustTokenPrivileges = modadvapi32.NewProc("AdjustTokenPrivileges")
procLookupPrivilegeNameW = modadvapi32.NewProc("LookupPrivilegeNameW")
procLookupPrivilegeValueW = modadvapi32.NewProc("LookupPrivilegeValueW")
procCreateToolhelp32Snapshot = modkernel32.NewProc("CreateToolhelp32Snapshot")
procFindFirstVolumeW = modkernel32.NewProc("FindFirstVolumeW")
procFindNextVolumeW = modkernel32.NewProc("FindNextVolumeW")
procFindVolumeClose = modkernel32.NewProc("FindVolumeClose")
procGetDiskFreeSpaceExW = modkernel32.NewProc("GetDiskFreeSpaceExW")
procGetDriveTypeW = modkernel32.NewProc("GetDriveTypeW")
procGetLogicalDriveStringsW = modkernel32.NewProc("GetLogicalDriveStringsW")
procGetSystemTimes = modkernel32.NewProc("GetSystemTimes")
procGetTickCount64 = modkernel32.NewProc("GetTickCount64")
procGetVolumeInformationW = modkernel32.NewProc("GetVolumeInformationW")
procGetVolumePathNamesForVolumeNameW = modkernel32.NewProc("GetVolumePathNamesForVolumeNameW")
procGlobalMemoryStatusEx = modkernel32.NewProc("GlobalMemoryStatusEx")
procProcess32FirstW = modkernel32.NewProc("Process32FirstW")
procProcess32NextW = modkernel32.NewProc("Process32NextW")
procReadProcessMemory = modkernel32.NewProc("ReadProcessMemory")
procNtQueryInformationProcess = modntdll.NewProc("NtQueryInformationProcess")
procNtQuerySystemInformation = modntdll.NewProc("NtQuerySystemInformation")
procEnumProcesses = modpsapi.NewProc("EnumProcesses")
procGetProcessImageFileNameW = modpsapi.NewProc("GetProcessImageFileNameW")
procGetProcessMemoryInfo = modpsapi.NewProc("GetProcessMemoryInfo")
)
func _AdjustTokenPrivileges(token syscall.Token, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) {
var _p0 uint32
if releaseAll {
_p0 = 1
}
r0, _, e1 := syscall.Syscall6(procAdjustTokenPrivileges.Addr(), 6, uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(input)), uintptr(outputSize), uintptr(unsafe.Pointer(output)), uintptr(unsafe.Pointer(requiredSize)))
success = r0 != 0
if true {
err = errnoErr(e1)
}
return
}
func _LookupPrivilegeName(systemName string, luid *int64, buffer *uint16, size *uint32) (err error) {
var _p0 *uint16
_p0, err = syscall.UTF16PtrFromString(systemName)
if err != nil {
return
}
return __LookupPrivilegeName(_p0, luid, buffer, size)
}
func __LookupPrivilegeName(systemName *uint16, luid *int64, buffer *uint16, size *uint32) (err error) {
r1, _, e1 := syscall.Syscall6(procLookupPrivilegeNameW.Addr(), 4, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(luid)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), 0, 0)
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func _LookupPrivilegeValue(systemName string, name string, luid *int64) (err error) {
var _p0 *uint16
_p0, err = syscall.UTF16PtrFromString(systemName)
if err != nil {
return
}
var _p1 *uint16
_p1, err = syscall.UTF16PtrFromString(name)
if err != nil {
return
}
return __LookupPrivilegeValue(_p0, _p1, luid)
}
func __LookupPrivilegeValue(systemName *uint16, name *uint16, luid *int64) (err error) {
r1, _, e1 := syscall.Syscall(procLookupPrivilegeValueW.Addr(), 3, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(luid)))
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func _CreateToolhelp32Snapshot(flags uint32, processID uint32) (handle syscall.Handle, err error) {
r0, _, e1 := syscall.Syscall(procCreateToolhelp32Snapshot.Addr(), 2, uintptr(flags), uintptr(processID), 0)
handle = syscall.Handle(r0)
if handle == 0 {
err = errnoErr(e1)
}
return
}
func _FindFirstVolume(volumeName *uint16, size uint32) (handle syscall.Handle, err error) {
r0, _, e1 := syscall.Syscall(procFindFirstVolumeW.Addr(), 2, uintptr(unsafe.Pointer(volumeName)), uintptr(size), 0)
handle = syscall.Handle(r0)
if handle == 0 {
err = errnoErr(e1)
}
return
}
func _FindNextVolume(handle syscall.Handle, volumeName *uint16, size uint32) (err error) {
r1, _, e1 := syscall.Syscall(procFindNextVolumeW.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(volumeName)), uintptr(size))
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func _FindVolumeClose(handle syscall.Handle) (err error) {
r1, _, e1 := syscall.Syscall(procFindVolumeClose.Addr(), 1, uintptr(handle), 0, 0)
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func _GetDiskFreeSpaceEx(directoryName *uint16, freeBytesAvailable *uint64, totalNumberOfBytes *uint64, totalNumberOfFreeBytes *uint64) (err error) {
r1, _, e1 := syscall.Syscall6(procGetDiskFreeSpaceExW.Addr(), 4, uintptr(unsafe.Pointer(directoryName)), uintptr(unsafe.Pointer(freeBytesAvailable)), uintptr(unsafe.Pointer(totalNumberOfBytes)), uintptr(unsafe.Pointer(totalNumberOfFreeBytes)), 0, 0)
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func _GetDriveType(rootPathName *uint16) (dt DriveType, err error) {
r0, _, e1 := syscall.Syscall(procGetDriveTypeW.Addr(), 1, uintptr(unsafe.Pointer(rootPathName)), 0, 0)
dt = DriveType(r0)
if dt == 0 {
err = errnoErr(e1)
}
return
}
func _GetLogicalDriveStringsW(bufferLength uint32, buffer *uint16) (length uint32, err error) {
r0, _, e1 := syscall.Syscall(procGetLogicalDriveStringsW.Addr(), 2, uintptr(bufferLength), uintptr(unsafe.Pointer(buffer)), 0)
length = uint32(r0)
if length == 0 {
err = errnoErr(e1)
}
return
}
func _GetSystemTimes(idleTime *syscall.Filetime, kernelTime *syscall.Filetime, userTime *syscall.Filetime) (err error) {
r1, _, e1 := syscall.Syscall(procGetSystemTimes.Addr(), 3, uintptr(unsafe.Pointer(idleTime)), uintptr(unsafe.Pointer(kernelTime)), uintptr(unsafe.Pointer(userTime)))
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func _GetTickCount64() (uptime uint64, err error) {
r0, _, e1 := syscall.Syscall(procGetTickCount64.Addr(), 0, 0, 0, 0)
uptime = uint64(r0)
if uptime == 0 {
err = errnoErr(e1)
}
return
}
func _GetVolumeInformation(rootPathName *uint16, volumeName *uint16, volumeNameSize uint32, volumeSerialNumber *uint32, maximumComponentLength *uint32, fileSystemFlags *uint32, fileSystemName *uint16, fileSystemNameSize uint32) (success bool, err error) {
r0, _, e1 := syscall.Syscall9(procGetVolumeInformationW.Addr(), 8, uintptr(unsafe.Pointer(rootPathName)), uintptr(unsafe.Pointer(volumeName)), uintptr(volumeNameSize), uintptr(unsafe.Pointer(volumeSerialNumber)), uintptr(unsafe.Pointer(maximumComponentLength)), uintptr(unsafe.Pointer(fileSystemFlags)), uintptr(unsafe.Pointer(fileSystemName)), uintptr(fileSystemNameSize), 0)
success = r0 != 0
if true {
err = errnoErr(e1)
}
return
}
func _GetVolumePathNamesForVolumeName(volumeName string, buffer *uint16, bufferSize uint32, length *uint32) (err error) {
var _p0 *uint16
_p0, err = syscall.UTF16PtrFromString(volumeName)
if err != nil {
return
}
return __GetVolumePathNamesForVolumeName(_p0, buffer, bufferSize, length)
}
func __GetVolumePathNamesForVolumeName(volumeName *uint16, buffer *uint16, bufferSize uint32, length *uint32) (err error) {
r1, _, e1 := syscall.Syscall6(procGetVolumePathNamesForVolumeNameW.Addr(), 4, uintptr(unsafe.Pointer(volumeName)), uintptr(unsafe.Pointer(buffer)), uintptr(bufferSize), uintptr(unsafe.Pointer(length)), 0, 0)
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func _GlobalMemoryStatusEx(buffer *MemoryStatusEx) (err error) {
r1, _, e1 := syscall.Syscall(procGlobalMemoryStatusEx.Addr(), 1, uintptr(unsafe.Pointer(buffer)), 0, 0)
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func _Process32First(handle syscall.Handle, processEntry32 *ProcessEntry32) (err error) {
r1, _, e1 := syscall.Syscall(procProcess32FirstW.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(processEntry32)), 0)
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func _Process32Next(handle syscall.Handle, processEntry32 *ProcessEntry32) (err error) {
r1, _, e1 := syscall.Syscall(procProcess32NextW.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(processEntry32)), 0)
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func _ReadProcessMemory(handle syscall.Handle, baseAddress uintptr, buffer uintptr, size uintptr, numRead *uintptr) (err error) {
r1, _, e1 := syscall.Syscall6(procReadProcessMemory.Addr(), 5, uintptr(handle), uintptr(baseAddress), uintptr(buffer), uintptr(size), uintptr(unsafe.Pointer(numRead)), 0)
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func _NtQueryInformationProcess(processHandle syscall.Handle, processInformationClass uint32, processInformation *byte, processInformationLength uint32, returnLength *uint32) (ntstatus uint32, err error) {
r0, _, e1 := syscall.Syscall6(procNtQueryInformationProcess.Addr(), 5, uintptr(processHandle), uintptr(processInformationClass), uintptr(unsafe.Pointer(processInformation)), uintptr(processInformationLength), uintptr(unsafe.Pointer(returnLength)), 0)
ntstatus = uint32(r0)
if ntstatus == 0 {
err = errnoErr(e1)
}
return
}
func _NtQuerySystemInformation(systemInformationClass uint32, systemInformation *byte, systemInformationLength uint32, returnLength *uint32) (ntstatus uint32, err error) {
r0, _, e1 := syscall.Syscall6(procNtQuerySystemInformation.Addr(), 4, uintptr(systemInformationClass), uintptr(unsafe.Pointer(systemInformation)), uintptr(systemInformationLength), uintptr(unsafe.Pointer(returnLength)), 0, 0)
ntstatus = uint32(r0)
if ntstatus == 0 {
err = errnoErr(e1)
}
return
}
func _EnumProcesses(processIds *uint32, sizeBytes uint32, bytesReturned *uint32) (err error) {
r1, _, e1 := syscall.Syscall(procEnumProcesses.Addr(), 3, uintptr(unsafe.Pointer(processIds)), uintptr(sizeBytes), uintptr(unsafe.Pointer(bytesReturned)))
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func _GetProcessImageFileName(handle syscall.Handle, outImageFileName *uint16, size uint32) (length uint32, err error) {
r0, _, e1 := syscall.Syscall(procGetProcessImageFileNameW.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(outImageFileName)), uintptr(size))
length = uint32(r0)
if length == 0 {
err = errnoErr(e1)
}
return
}
func _GetProcessMemoryInfo(handle syscall.Handle, psmemCounters *ProcessMemoryCountersEx, cb uint32) (err error) {
r1, _, e1 := syscall.Syscall(procGetProcessMemoryInfo.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(psmemCounters)), uintptr(cb))
if r1 == 0 {
err = errnoErr(e1)
}
return
}

View File

@ -33,6 +33,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/google/uuid"
"github.com/status-im/status-go/extkeys"
)
const (
@ -46,6 +47,13 @@ type Key struct {
// we only store privkey as pubkey/address can be derived from it
// privkey in this struct is always in plaintext
PrivateKey *ecdsa.PrivateKey
// ExtendedKey is the extended key of the PrivateKey itself, and it's used
// to derive child keys.
ExtendedKey *extkeys.ExtendedKey
// SubAccountIndex is DEPRECATED
// It was use in Status to keep track of the number of sub-account created
// before having multi-account support.
SubAccountIndex uint32
}
type keyStore interface {
@ -65,10 +73,12 @@ type plainKeyJSON struct {
}
type encryptedKeyJSONV3 struct {
Address string `json:"address"`
Crypto CryptoJSON `json:"crypto"`
Id string `json:"id"`
Version int `json:"version"`
Address string `json:"address"`
Crypto CryptoJSON `json:"crypto"`
Id string `json:"id"`
Version int `json:"version"`
ExtendedKey CryptoJSON `json:"extendedkey"`
SubAccountIndex uint32 `json:"subaccountindex"`
}
type encryptedKeyJSONV1 struct {
@ -143,6 +153,43 @@ func newKeyFromECDSA(privateKeyECDSA *ecdsa.PrivateKey) *Key {
return key
}
func newKeyForPurposeFromExtendedKey(keyPurpose extkeys.KeyPurpose, extKey *extkeys.ExtendedKey) (*Key, error) {
var (
extChild1, extChild2 *extkeys.ExtendedKey
err error
)
if extKey.Depth == 0 { // we are dealing with master key
// CKD#1 - main account
extChild1, err = extKey.ChildForPurpose(keyPurpose, 0)
if err != nil {
return &Key{}, err
}
// CKD#2 - sub-accounts root
extChild2, err = extKey.ChildForPurpose(keyPurpose, 1)
if err != nil {
return &Key{}, err
}
} else { // we are dealing with non-master key, so it is safe to persist and extend from it
extChild1 = extKey
extChild2 = extKey
}
privateKeyECDSA := extChild1.ToECDSA()
id, err := uuid.NewRandom()
if err != nil {
return nil, err
}
key := &Key{
Id: id,
Address: crypto.PubkeyToAddress(privateKeyECDSA.PublicKey),
PrivateKey: privateKeyECDSA,
ExtendedKey: extChild2,
}
return key, nil
}
// NewKeyForDirectICAP generates a key whose address fits into < 155 bits so it can fit
// into the Direct ICAP spec. for simplicity and easier compatibility with other libs, we
// retry until the first byte is 0.

View File

@ -37,6 +37,8 @@ import (
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/event"
"github.com/google/uuid"
"github.com/status-im/status-go/extkeys"
)
var (
@ -234,6 +236,11 @@ func (ks *KeyStore) Accounts() []accounts.Account {
return ks.cache.accounts()
}
// AccountDecryptedKey returns decrypted key for account (provided that password is correct).
func (ks *KeyStore) AccountDecryptedKey(a accounts.Account, auth string) (accounts.Account, *Key, error) {
return ks.getDecryptedKey(a, auth)
}
// Delete deletes the key matched by account if the passphrase is correct.
// If the account contains no filename, the address must match a unique key.
func (ks *KeyStore) Delete(a accounts.Account, passphrase string) error {
@ -460,13 +467,71 @@ func (ks *KeyStore) ImportECDSA(priv *ecdsa.PrivateKey, passphrase string) (acco
key := newKeyFromECDSA(priv)
if ks.cache.hasAddress(key.Address) {
return accounts.Account{
Address: key.Address,
}, ErrAccountAlreadyExists
return accounts.Account{}, ErrAccountAlreadyExists
}
return ks.importKey(key, passphrase)
}
// ImportSingleExtendedKey imports an extended key setting it in both the PrivateKey and ExtendedKey fields
// of the Key struct.
// ImportExtendedKey is used in older version of Status where PrivateKey is set to be the BIP44 key at index 0,
// and ExtendedKey is the extended key of the BIP44 key at index 1.
func (ks *KeyStore) ImportSingleExtendedKey(extKey *extkeys.ExtendedKey, passphrase string) (accounts.Account, error) {
privateKeyECDSA := extKey.ToECDSA()
id, err := uuid.NewRandom()
if err != nil {
return accounts.Account{}, err
}
key := &Key{
Id: id,
Address: crypto.PubkeyToAddress(privateKeyECDSA.PublicKey),
PrivateKey: privateKeyECDSA,
ExtendedKey: extKey,
}
if ks.cache.hasAddress(key.Address) {
return accounts.Account{}, ErrAccountAlreadyExists
}
return ks.importKey(key, passphrase)
}
// ImportExtendedKey stores ECDSA key (obtained from extended key) along with CKD#2 (root for sub-accounts)
// If key file is not found, it is created. Key is encrypted with the given passphrase.
// Deprecated: status-go is now using ImportSingleExtendedKey
func (ks *KeyStore) ImportExtendedKey(extKey *extkeys.ExtendedKey, passphrase string) (accounts.Account, error) {
return ks.ImportExtendedKeyForPurpose(extkeys.KeyPurposeWallet, extKey, passphrase)
}
// ImportExtendedKeyForPurpose stores ECDSA key (obtained from extended key) along with CKD#2 (root for sub-accounts)
// If key file is not found, it is created. Key is encrypted with the given passphrase.
// Deprecated: status-go is now using ImportSingleExtendedKey
func (ks *KeyStore) ImportExtendedKeyForPurpose(keyPurpose extkeys.KeyPurpose, extKey *extkeys.ExtendedKey, passphrase string) (accounts.Account, error) {
key, err := newKeyForPurposeFromExtendedKey(keyPurpose, extKey)
if err != nil {
zeroKey(key.PrivateKey)
return accounts.Account{}, err
}
// if account is already imported, return cached version
if ks.cache.hasAddress(key.Address) {
a := accounts.Account{
Address: key.Address,
}
ks.cache.maybeReload()
ks.cache.mu.Lock()
a, err := ks.cache.find(a)
ks.cache.mu.Unlock()
if err != nil {
zeroKey(key.PrivateKey)
return a, err
}
return a, nil
}
return ks.importKey(key, passphrase)
}
func (ks *KeyStore) importKey(key *Key, passphrase string) (accounts.Account, error) {
a := accounts.Account{Address: key.Address, URL: accounts.URL{Scheme: KeyStoreScheme, Path: ks.storage.JoinPath(keyFileName(key.Address))}}
if err := ks.storage.StoreKey(a.URL.Path, key, passphrase); err != nil {
@ -477,6 +542,15 @@ func (ks *KeyStore) importKey(key *Key, passphrase string) (accounts.Account, er
return a, nil
}
func (ks *KeyStore) IncSubAccountIndex(a accounts.Account, passphrase string) error {
a, key, err := ks.getDecryptedKey(a, passphrase)
if err != nil {
return err
}
key.SubAccountIndex++
return ks.storage.StoreKey(a.URL.Path, key, passphrase)
}
// Update changes the passphrase of an existing account.
func (ks *KeyStore) Update(a accounts.Account, passphrase, newPassphrase string) error {
a, key, err := ks.getDecryptedKey(a, passphrase)
@ -500,6 +574,10 @@ func (ks *KeyStore) ImportPreSaleKey(keyJSON []byte, passphrase string) (account
// zeroKey zeroes a private key in memory.
func zeroKey(k *ecdsa.PrivateKey) {
if k == nil {
return
}
b := k.D.Bits()
for i := range b {
b[i] = 0

View File

@ -43,6 +43,7 @@ import (
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/crypto"
"github.com/google/uuid"
"github.com/status-im/status-go/extkeys"
"golang.org/x/crypto/pbkdf2"
"golang.org/x/crypto/scrypt"
)
@ -189,15 +190,68 @@ func EncryptKey(key *Key, auth string, scryptN, scryptP int) ([]byte, error) {
if err != nil {
return nil, err
}
encryptedExtendedKey, err := EncryptExtendedKey(key.ExtendedKey, auth, scryptN, scryptP)
if err != nil {
return nil, err
}
encryptedKeyJSONV3 := encryptedKeyJSONV3{
hex.EncodeToString(key.Address[:]),
cryptoStruct,
key.Id.String(),
version,
encryptedExtendedKey,
key.SubAccountIndex,
}
return json.Marshal(encryptedKeyJSONV3)
}
func EncryptExtendedKey(extKey *extkeys.ExtendedKey, auth string, scryptN, scryptP int) (CryptoJSON, error) {
if extKey == nil {
return CryptoJSON{}, nil
}
authArray := []byte(auth)
salt := make([]byte, 32)
if _, err := io.ReadFull(rand.Reader, salt); err != nil {
panic("reading from crypto/rand failed: " + err.Error())
}
derivedKey, err := scrypt.Key(authArray, salt, scryptN, scryptR, scryptP, scryptDKLen)
if err != nil {
return CryptoJSON{}, err
}
encryptKey := derivedKey[:16]
keyBytes := []byte(extKey.String())
iv := make([]byte, aes.BlockSize) // 16
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
panic("reading from crypto/rand failed: " + err.Error())
}
cipherText, err := aesCTRXOR(encryptKey, keyBytes, iv)
if err != nil {
return CryptoJSON{}, err
}
mac := crypto.Keccak256(derivedKey[16:32], cipherText)
scryptParamsJSON := make(map[string]interface{}, 5)
scryptParamsJSON["n"] = scryptN
scryptParamsJSON["r"] = scryptR
scryptParamsJSON["p"] = scryptP
scryptParamsJSON["dklen"] = scryptDKLen
scryptParamsJSON["salt"] = hex.EncodeToString(salt)
cipherParamsJSON := cipherparamsJSON{
IV: hex.EncodeToString(iv),
}
return CryptoJSON{
Cipher: "aes-128-ctr",
CipherText: hex.EncodeToString(cipherText),
CipherParams: cipherParamsJSON,
KDF: "scrypt",
KDFParams: scryptParamsJSON,
MAC: hex.EncodeToString(mac),
}, nil
}
// DecryptKey decrypts a key from a json blob, returning the private key itself.
func DecryptKey(keyjson []byte, auth string) (*Key, error) {
// Parse the json into a simple map to fetch the key version
@ -209,19 +263,41 @@ func DecryptKey(keyjson []byte, auth string) (*Key, error) {
var (
keyBytes, keyId []byte
err error
extKeyBytes []byte
extKey *extkeys.ExtendedKey
)
subAccountIndex, ok := m["subaccountindex"].(float64)
if !ok {
subAccountIndex = 0
}
if version, ok := m["version"].(string); ok && version == "1" {
k := new(encryptedKeyJSONV1)
if err := json.Unmarshal(keyjson, k); err != nil {
return nil, err
}
keyBytes, keyId, err = decryptKeyV1(k, auth)
if err != nil {
return nil, err
}
extKey, err = extkeys.NewKeyFromString(extkeys.EmptyExtendedKeyString)
} else {
k := new(encryptedKeyJSONV3)
if err := json.Unmarshal(keyjson, k); err != nil {
return nil, err
}
keyBytes, keyId, err = decryptKeyV3(k, auth)
if err != nil {
return nil, err
}
extKeyBytes, err = decryptExtendedKey(k, auth)
if err != nil {
return nil, err
}
extKey, err = extkeys.NewKeyFromString(string(extKeyBytes))
}
// Handle any decryption errors and return the key
if err != nil {
@ -233,9 +309,11 @@ func DecryptKey(keyjson []byte, auth string) (*Key, error) {
return nil, err
}
return &Key{
Id: id,
Address: crypto.PubkeyToAddress(key.PublicKey),
PrivateKey: key,
Id: id,
Address: crypto.PubkeyToAddress(key.PublicKey),
PrivateKey: key,
ExtendedKey: extKey,
SubAccountIndex: uint32(subAccountIndex),
}, nil
}
@ -329,6 +407,51 @@ func decryptKeyV1(keyProtected *encryptedKeyJSONV1, auth string) (keyBytes []byt
return plainText, keyId, err
}
func decryptExtendedKey(keyProtected *encryptedKeyJSONV3, auth string) (plainText []byte, err error) {
if len(keyProtected.ExtendedKey.CipherText) == 0 {
return []byte(extkeys.EmptyExtendedKeyString), nil
}
if keyProtected.Version != version {
return nil, fmt.Errorf("Version not supported: %v", keyProtected.Version)
}
if keyProtected.ExtendedKey.Cipher != "aes-128-ctr" {
return nil, fmt.Errorf("Cipher not supported: %v", keyProtected.ExtendedKey.Cipher)
}
mac, err := hex.DecodeString(keyProtected.ExtendedKey.MAC)
if err != nil {
return nil, err
}
iv, err := hex.DecodeString(keyProtected.ExtendedKey.CipherParams.IV)
if err != nil {
return nil, err
}
cipherText, err := hex.DecodeString(keyProtected.ExtendedKey.CipherText)
if err != nil {
return nil, err
}
derivedKey, err := getKDFKey(keyProtected.ExtendedKey, auth)
if err != nil {
return nil, err
}
calculatedMAC := crypto.Keccak256(derivedKey[16:32], cipherText)
if !bytes.Equal(calculatedMAC, mac) {
return nil, ErrDecrypt
}
plainText, err = aesCTRXOR(derivedKey[:16], cipherText, iv)
if err != nil {
return nil, err
}
return plainText, err
}
func getKDFKey(cryptoJSON CryptoJSON, auth string) ([]byte, error) {
authArray := []byte(auth)
salt, err := hex.DecodeString(cryptoJSON.KDFParams["salt"].(string))

View File

@ -143,6 +143,8 @@ type Downloader struct {
quitCh chan struct{} // Quit channel to signal termination
quitLock sync.Mutex // Lock to prevent double closes
downloads sync.WaitGroup // Keeps track of the currently active downloads
// Testing hooks
syncInitHook func(uint64, uint64) // Method to call upon initiating a new sync run
bodyFetchHook func([]*types.Header) // Method to call upon starting a block body fetch
@ -439,7 +441,9 @@ func (d *Downloader) getMode() SyncMode {
// specified peer and head hash.
func (d *Downloader) syncWithPeer(p *peerConnection, hash common.Hash, td *big.Int) (err error) {
d.mux.Post(StartEvent{})
d.downloads.Add(1)
defer func() {
d.downloads.Done()
// reset on error
if err != nil {
d.mux.Post(FailedEvent{err})
@ -560,14 +564,22 @@ func (d *Downloader) syncWithPeer(p *peerConnection, hash common.Hash, td *big.I
} else if mode == FullSync {
fetchers = append(fetchers, d.processFullSyncContent)
}
return d.spawnSync(fetchers)
return d.spawnSync(errCanceled, fetchers)
}
// spawnSync runs d.process and all given fetcher functions to completion in
// separate goroutines, returning the first error that appears.
func (d *Downloader) spawnSync(fetchers []func() error) error {
func (d *Downloader) spawnSync(errCancel error, fetchers []func() error) error {
d.cancelLock.Lock()
select {
case <-d.cancelCh:
d.cancelLock.Unlock()
return errCancel
default:
}
errc := make(chan error, len(fetchers))
d.cancelWg.Add(len(fetchers))
d.cancelLock.Unlock()
for _, fn := range fetchers {
fn := fn
go func() { defer d.cancelWg.Done(); errc <- fn() }()
@ -632,6 +644,10 @@ func (d *Downloader) Terminate() {
// Cancel any pending download requests
d.Cancel()
// Wait, so external dependencies aren't destroyed
// until the download processing is done.
d.downloads.Wait()
}
// fetchHead retrieves the head header and prior pivot block (if available) from

View File

@ -22,6 +22,7 @@ require (
github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf
github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498
github.com/edsrzf/mmap-go v1.0.0
github.com/elastic/gosigar v0.14.1
github.com/fatih/color v1.7.0
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff
@ -55,6 +56,7 @@ require (
github.com/rs/cors v1.7.0
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible
github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4
github.com/status-im/status-go/extkeys v1.1.2
github.com/stretchr/testify v1.7.0
github.com/syndtr/goleveldb v1.0.1-0.20210305035536-64b5b1c73954
github.com/tklauser/go-sysconf v0.3.5 // indirect

View File

@ -80,6 +80,7 @@ github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx2
github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw=
github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d h1:yJzD/yFppdVCf6ApMkVy8cUxV0XrxdP9rVf6D87/Mng=
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg=
github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY=
@ -98,10 +99,8 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cloudflare/cloudflare-go v0.14.0 h1:gFqGlGl/5f9UGXAaKapCGUfaTCgRKKnzu2VvzMZlOFA=
github.com/cloudflare/cloudflare-go v0.14.0/go.mod h1:EnwdgGMaFOruiPZRFSgn+TsQ3hQ7C/YWzIGLeu5c304=
github.com/consensys/bavard v0.1.8-0.20210406032232-f3452dc9b572/go.mod h1:Bpd0/3mZuaj6Sj+PqrmIquiOKy397AKGThQPaGzNXAQ=
github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f h1:C43yEtQ6NIf4ftFXD/V55gnGFgPbMQobd//YlnLjUJ8=
github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f/go.mod h1:815PAHg3wvysy0SyIqanF8gZ0Y1wjk/hrDHD/iT88+Q=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/dave/jennifer v1.2.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg=
@ -111,28 +110,28 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea h1:j4317fAZh7X6GqbFowYdYdI0L9bwxL07jyPZIdepyZ0=
github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-bitstream v0.0.0-20180413035011-3522498ce2c8/go.mod h1:VMaSuZ+SZcx/wljOQKvp5srsbCiKDEb6K2wC4+PiBmQ=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/dlclark/regexp2 v1.2.0 h1:8sAhBGEM0dRWogWqWyQeIJnxjWO6oIjl8FKqREDsGfk=
github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf h1:sh8rkQZavChcmakYiSlqu2425CHyFXLZZnvm7PDpU8M=
github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498 h1:Y9vTBSsV4hSwPSj4bacAU/eSnV3dAxVpepaghAdhGoQ=
github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498/go.mod h1:Mw6PkjjMXWbTj+nnj4s3QPXq1jaT0s5pC0iFD4+BOAA=
github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts=
github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw=
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
github.com/elastic/gosigar v0.14.1 h1:T0aQ7n/n2ZA9W7DmAnj60v+qzqKERdBgJBO1CG2W6rc=
github.com/elastic/gosigar v0.14.1/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/ethereum/go-ethereum v1.9.5/go.mod h1:PwpWDrCLZrV+tfrhqqF6kPknbISMHaJv9Ln3kPCZLwY=
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c=
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0=
github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI=
github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww=
@ -140,10 +139,8 @@ github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd/go.mod
github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-kit/kit v0.8.0 h1:Wz+5lgoB0kkuqLEc6NVmwRknTKP6dTGbSqvhZtBI/j0=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-ole/go-ole v1.2.1 h1:2lOsA72HgjxAuMlKpFiCbHTvu44PIVkZ5hqm3RSdI/E=
github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
@ -186,9 +183,7 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa h1:Q75Upo5UN4JbPFURXZ8nLKYUvF85dyFRop/vQ0Rv+64=
github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
@ -240,7 +235,6 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/jsternberg/zap-logfmt v1.0.0/go.mod h1:uvPs/4X51zdkcm5jXl5SYoN+4RK21K8mysFmDaM/h+o=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0 h1:TDTW5Yz1mjftljbcKqRcrYhd4XeOoI98t+9HbQbYf7g=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
github.com/jwilder/encoding v0.0.0-20170811194829-b4e1701a28ef/go.mod h1:Ct9fl0F6iIOGgxJ5npU/IUOhOhqlVrGjyIZc8/MagT0=
@ -254,16 +248,11 @@ github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM52
github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg=
github.com/klauspost/pgzip v1.0.2-0.20170402124221-0bf5dcad4ada/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c=
github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
@ -289,7 +278,6 @@ github.com/naoina/go-stringutil v0.1.0 h1:rCUeRUHjBjGTSHl0VC00jUPLz8/F9dDzYI70Hz
github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0=
github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416 h1:shk/vn9oCoOTmwcouEdwIeOtOGA/ELRUw/GwvxwfT+0=
github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E=
github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
@ -297,11 +285,9 @@ github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA=
github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/opentracing/opentracing-go v1.0.3-0.20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
@ -318,7 +304,6 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/term v0.0.0-20180730021639-bffc007b7fd5/go.mod h1:eCbImbZ95eXtAUIbLAuAVnBnwf83mjf6QIVH8SHYwqQ=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
@ -354,13 +339,14 @@ github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4 h1:Gb2Tyox57NRNuZ2d3rmvB3pcmbu7O1RS3m8WRx7ilrg=
github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q=
github.com/status-im/status-go/extkeys v1.1.2 h1:FSjARgDathJ3rIapJt851LsIXP9Oyuu2M2jPJKuzloU=
github.com/status-im/status-go/extkeys v1.1.2/go.mod h1:hCmFzb2jiiVF2voZKYbzuhOQiHHCmyLJsZJXrFFg7BY=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.0/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/syndtr/goleveldb v1.0.1-0.20210305035536-64b5b1c73954 h1:xQdMZ1WLrgkkvOZ/LDQxjVxMLdby7osSh4ZEVa5sIjs=
github.com/syndtr/goleveldb v1.0.1-0.20210305035536-64b5b1c73954/go.mod h1:u2MKkTVTVJWe5D1rCvame8WqhBd88EuIwODJZ1VHCPM=
@ -388,6 +374,7 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190909091759-094676da4a83/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
@ -456,6 +443,7 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -485,7 +473,6 @@ golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988 h1:EjgCl+fVlIaPJSori0ikSz3uV0DOHKWOJFpv1sAAhBM=
golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@ -527,7 +514,6 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
gonum.org/v1/gonum v0.0.0-20181121035319-3f7ecaa7e8ca/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
@ -575,7 +561,6 @@ google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyz
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
@ -583,7 +568,6 @@ gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c=
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6 h1:a6cXbcDDUkSBlpnkWV1bJ+vv3mOgQEltEJ2rPxroVu0=
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/urfave/cli.v1 v1.20.0 h1:NdAVW6RYxDif9DhDHaAortIu956m2c0v+09AZBPTbE0=
gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0=
@ -592,11 +576,8 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

View File

@ -219,6 +219,14 @@ func NewPrivateAccountAPI(b Backend, nonceLock *AddrLocker) *PrivateAccountAPI {
}
}
func NewSubsetOfPrivateAccountAPI(am *accounts.Manager) *PrivateAccountAPI {
return &PrivateAccountAPI{
am: am,
nonceLock: nil,
b: nil,
}
}
// listAccounts will return a list of addresses for accounts this node manages.
func (s *PrivateAccountAPI) ListAccounts() []common.Address {
return s.am.Accounts()
@ -449,7 +457,7 @@ func (s *PrivateAccountAPI) Sign(ctx context.Context, data hexutil.Bytes, addr c
// Look up the wallet containing the requested signer
account := accounts.Account{Address: addr}
wallet, err := s.b.AccountManager().Find(account)
wallet, err := s.am.Find(account)
if err != nil {
return nil, err
}

View File

@ -8,7 +8,6 @@ import (
"reflect"
"strconv"
"strings"
"sync"
"sync/atomic"
"time"
"unicode/utf8"
@ -45,13 +44,6 @@ var locationEnabled uint32
// padded to to aid in alignment.
var locationLength uint32
// fieldPadding is a global map with maximum field value lengths seen until now
// to allow padding log contexts in a bit smarter way.
var fieldPadding = make(map[string]int)
// fieldPaddingLock is a global mutex protecting the field padding map.
var fieldPaddingLock sync.RWMutex
type Format interface {
Format(r *Record) []byte
}
@ -171,19 +163,6 @@ func logfmt(buf *bytes.Buffer, ctx []interface{}, color int, term bool) {
k, v = errorKey, formatLogfmtValue(k, term)
}
// XXX: we should probably check that all of your key bytes aren't invalid
fieldPaddingLock.RLock()
padding := fieldPadding[k]
fieldPaddingLock.RUnlock()
length := utf8.RuneCountInString(v)
if padding < length && length <= termCtxMaxPadding {
padding = length
fieldPaddingLock.Lock()
fieldPadding[k] = padding
fieldPaddingLock.Unlock()
}
if color > 0 {
fmt.Fprintf(buf, "\x1b[%dm%s\x1b[0m=", color, k)
} else {
@ -191,9 +170,6 @@ func logfmt(buf *bytes.Buffer, ctx []interface{}, color int, term bool) {
buf.WriteByte('=')
}
buf.WriteString(v)
if i < len(ctx)-2 && padding > length {
buf.Write(bytes.Repeat([]byte{' '}, padding-length))
}
}
buf.WriteByte('\n')
}

View File

@ -0,0 +1,14 @@
// +build !ios,!android
package metrics
import "github.com/elastic/gosigar"
func readCPUStats(stats *CPUStats) {
global := gosigar.Cpu{}
global.Get()
stats.GlobalTime = int64(global.User + global.Nice + global.Sys)
stats.GlobalWait = int64(global.Wait)
stats.LocalTime = getProcessCPUTime()
}

View File

@ -0,0 +1,5 @@
// +build android
package metrics
func readCPUStats(stats *CPUStats) {}

View File

@ -0,0 +1,5 @@
// +build ios
package metrics
func readCPUStats(stats *CPUStats) {}

View File

@ -8,6 +8,7 @@ package metrics
import (
"os"
"runtime"
"strconv"
"strings"
"time"
@ -26,6 +27,10 @@ var Enabled = false
// for health monitoring and debug metrics that might impact runtime performance.
var EnabledExpensive = false
// EnabledStr has the same function as Enabled but
// it can be set during compilation (linking) time.
var EnabledStr = "false"
// enablerFlags is the CLI flag names to use to enable metrics collections.
var enablerFlags = []string{"metrics"}
@ -52,6 +57,12 @@ func init() {
}
}
}
if v, err := strconv.ParseBool(EnabledStr); err == nil && v {
log.Info("Enabling metrics collection")
Enabled = true
EnabledExpensive = true
}
}
// CollectProcessMetrics periodically collects various metrics about the running

View File

@ -30,6 +30,12 @@ import (
"github.com/ethereum/go-ethereum/rpc"
)
// PrivateAdminAPI is the collection of administrative API methods exposed only
// over a secure RPC channel.
type PrivateAdminAPI struct {
node *Node // Node interfaced by this API
}
// apis returns the collection of built-in RPC APIs.
func (n *Node) apis() []rpc.API {
return []rpc.API{
@ -94,6 +100,24 @@ func (api *privateAdminAPI) RemovePeer(url string) (bool, error) {
return true, nil
}
// DeletePeer disconnects and deletes forcefully a remote node.
func (api *PrivateAdminAPI) DeletePeer(url string) (bool, error) {
// Make sure the server is running, fail otherwise
server := api.node.Server()
if server == nil {
return false, ErrNodeStopped
}
// Try to remove the url as a static peer and return
node, err := enode.ParseV4(url)
if err != nil {
return false, fmt.Errorf("invalid enode: %v", err)
}
if err := server.DeletePeer(node); err != nil {
return false, err
}
return true, nil
}
// AddTrustedPeer allows a remote node to always connect, even if slots are full
func (api *privateAdminAPI) AddTrustedPeer(url string) (bool, error) {
// Make sure the server is running, fail otherwise

View File

@ -353,6 +353,36 @@ func (srv *Server) RemovePeer(node *enode.Node) {
}
}
// DeletePeer deletes the given node forcefully.
func (srv *Server) DeletePeer(node *enode.Node) error {
peerIDStr := node.ID().String()
srv.log.Info("DeletePeer called", "peerID", peerIDStr)
var peer *Peer
for _, p := range srv.Peers() {
if p.ID() == node.ID() {
peer = p
break
}
}
if peer == nil {
err := errors.New("peer not found")
srv.log.Info("DeletePeer failed to match a peer", "peerID", peerIDStr, "err", err)
return err
}
select {
case srv.delpeer <- peerDrop{peer, errors.New("forced delete"), true}:
case <-srv.quit:
}
srv.log.Info("DeletePeer passed the request to delpeer channel", "peerID", peerIDStr)
return nil
}
// AddTrustedPeer adds the given node to a reserved whitelist which allows the
// node to always connect, even if the slot are full.
func (srv *Server) AddTrustedPeer(node *enode.Node) {

13
vendor/github.com/status-im/status-go/extkeys/go.mod generated vendored Normal file
View File

@ -0,0 +1,13 @@
module github.com/status-im/status-go/extkeys
go 1.13
replace github.com/ethereum/go-ethereum v1.9.5 => github.com/status-im/go-ethereum v1.9.5-status.7
require (
github.com/btcsuite/btcd v0.20.1-beta
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d
github.com/ethereum/go-ethereum v1.9.5
golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c
golang.org/x/text v0.3.2
)

102
vendor/github.com/status-im/status-go/extkeys/go.sum generated vendored Normal file
View File

@ -0,0 +1,102 @@
bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8=
github.com/Azure/azure-pipeline-go v0.0.0-20180607212504-7571e8eb0876/go.mod h1:XA1kFWRVhSK+KNFiOhfv83Fv8L9achrP7OxIzeTn1Yg=
github.com/Azure/azure-storage-blob-go v0.0.0-20180712005634-eaae161d9d5e/go.mod h1:x2mtS6O3mnMEZOJp7d7oldh8IvatBrMfReiyQ+cKgKY=
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
github.com/allegro/bigcache v0.0.0-20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
github.com/btcsuite/btcd v0.20.1-beta h1:Ik4hyJqN8Jfyv3S4AGBOmyouMsYE3EdYODkMbQjwPGw=
github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d h1:yJzD/yFppdVCf6ApMkVy8cUxV0XrxdP9rVf6D87/Mng=
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg=
github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY=
github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY=
github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s=
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ=
github.com/dgrijalva/jwt-go v0.0.0-20170201225849-2268707a8f08/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/docker/docker v0.0.0-20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
github.com/elastic/gosigar v0.0.0-20180330100440-37f05ff46ffa/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs=
github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/gizak/termui v0.0.0-20170117222342-991cd3d38091/go.mod h1:PkJoWUt/zacQKysNfQtcw1RW+eK2SxkieVBtl+4ovLA=
github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
github.com/go-stack/stack v1.5.4/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/hashicorp/golang-lru v0.0.0-20160813221303-0a025b7e63ad/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/huin/goupnp v0.0.0-20161224104101-679507af18f3/go.mod h1:MZ2ZmwcBpvOoJ22IJsc7va19ZwoheaBk43rKg12SKag=
github.com/influxdata/influxdb v0.0.0-20180221223340-01288bdb0883/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY=
github.com/jackpal/go-nat-pmp v0.0.0-20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
github.com/julienschmidt/httprouter v0.0.0-20170430222011-975b5c4c7c21/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/karalabe/hid v0.0.0-20181128192157-d815e0c1a2e2/go.mod h1:YvbcH+3Wo6XPs9nkgTY3u19KXLauXW+J5nB7hEHuX0A=
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
github.com/maruel/panicparse v0.0.0-20160720141634-ad661195ed0e/go.mod h1:nty42YY5QByNC5MM7q/nj938VbgPU7avs45z6NClpxI=
github.com/mattn/go-colorable v0.1.0/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-isatty v0.0.0-20180830101745-3fb116b82035/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
github.com/naoina/toml v0.0.0-20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E=
github.com/nsf/termbox-go v0.0.0-20170211012700-3540b76b9c77/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ=
github.com/olekukonko/tablewriter v0.0.0-20170128050532-febf2d34b54a/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/opentracing/opentracing-go v0.0.0-20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/pborman/uuid v0.0.0-20170112150404-1b00554d8222/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34=
github.com/peterh/liner v0.0.0-20170902204657-a37ad3984311/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc=
github.com/pkg/errors v0.0.0-20171216070316-e881fd58d78e/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/prometheus v0.0.0-20170814170113-3101606756c5/go.mod h1:oAIUtOny2rjMX0OWN5vPR5/q/twIROJvdqnQKDdil/s=
github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho=
github.com/robertkrimen/otto v0.0.0-20170205013659-6a77b7cbc37d/go.mod h1:xvqspoSXJTIpemEonrMDFq6XzwHYYgToXWj5eRX1OtY=
github.com/rs/cors v0.0.0-20160617231935-a62a804a8a00/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
github.com/rs/xhandler v0.0.0-20160618193221-ed27b6fd6521/go.mod h1:RvLn4FgxWubrpZHtQLnOf6EwhN2hEMusxZOhcW9H3UQ=
github.com/status-im/go-ethereum v1.9.5-status.7 h1:DKH1GiF52LwaZaw6YDBliFEgm/JDsbIT+hn7ph6X94Q=
github.com/status-im/go-ethereum v1.9.5-status.7/go.mod h1:YyH5DKB6+z+Vaya7eIm67pnuPZ1oiUMbbsZW41ktN0g=
github.com/status-im/status-go/extkeys v1.0.0/go.mod h1:GdqJbrcpkNm5ZsSCpp+PdMxnXx+OcRBdm3PI0rs1FpU=
github.com/stretchr/testify v0.0.0-20170809224252-890a5c3458b4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/syndtr/goleveldb v0.0.0-20181128100959-b001fa50d6b2/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
github.com/uber/jaeger-client-go v0.0.0-20180607151842-f7e0d4744fa6/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
github.com/uber/jaeger-lib v0.0.0-20180615202729-a51202d6f4a7/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba h1:9bFeDpN3gTqNanMVqNcoR/pJQuP5uroC3t1D7eXozTE=
golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c h1:/nJuwDLoL/zrqY6gf57vxC+Pi+pZ8bfhpPkicO5H7W4=
golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20161208181325-20d25e280405 h1:829vOVxxusYHC+IqBtkX5mbKtsY9fheQiQn0MZRVLfQ=
gopkg.in/check.v1 v1.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c=
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20180302121509-abf0ba0be5d5/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns=
gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

491
vendor/github.com/status-im/status-go/extkeys/hdkey.go generated vendored Normal file
View File

@ -0,0 +1,491 @@
package extkeys
import (
"bytes"
"crypto/ecdsa"
"encoding/binary"
"encoding/hex"
"errors"
"fmt"
"math/big"
"github.com/btcsuite/btcd/btcec"
"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcutil"
"github.com/btcsuite/btcutil/base58"
)
// Implementation of the following BIPs:
// - BIP32 (https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki)
// - BIP39 (https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki)
// - BIP44 (https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki)
//
// Referencing
// https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki
// https://bitcoin.org/en/developer-guide#hardened-keys
// Reference Implementations
// https://github.com/btcsuite/btcutil/tree/master/hdkeychain
// https://github.com/WeMeetAgain/go-hdwallet
// https://github.com/ConsenSys/eth-lightwallet/blob/master/lib/keystore.js
// https://github.com/bitpay/bitcore-lib/tree/master/lib
// MUST CREATE HARDENED CHILDREN OF THE MASTER PRIVATE KEY (M) TO PREVENT
// A COMPROMISED CHILD KEY FROM COMPROMISING THE MASTER KEY.
// AS THERE ARE NO NORMAL CHILDREN FOR THE MASTER KEYS,
// THE MASTER PUBLIC KEY IS NOT USED IN HD WALLETS.
// ALL OTHER KEYS CAN HAVE NORMAL CHILDREN,
// SO THE CORRESPONDING EXTENDED PUBLIC KEYS MAY BE USED INSTEAD.
// TODO make sure we're doing this ^^^^ !!!!!!
type KeyPurpose int
const (
KeyPurposeWallet KeyPurpose = iota + 1
KeyPurposeChat
)
const (
// HardenedKeyStart defines a starting point for hardened key.
// Each extended key has 2^31 normal child keys and 2^31 hardened child keys.
// Thus the range for normal child keys is [0, 2^31 - 1] and the range for hardened child keys is [2^31, 2^32 - 1].
HardenedKeyStart = 0x80000000 // 2^31
// MinSeedBytes is the minimum number of bytes allowed for a seed to a master node.
MinSeedBytes = 16 // 128 bits
// MaxSeedBytes is the maximum number of bytes allowed for a seed to a master node.
MaxSeedBytes = 64 // 512 bits
// serializedKeyLen is the length of a serialized public or private
// extended key. It consists of 4 bytes version, 1 byte depth, 4 bytes
// fingerprint, 4 bytes child number, 32 bytes chain code, and 33 bytes
// public/private key data.
serializedKeyLen = 4 + 1 + 4 + 4 + 32 + 33 // 78 bytes
// CoinTypeBTC is BTC coin type
CoinTypeBTC = 0 // 0x80000000
// CoinTypeTestNet is test net coin type
CoinTypeTestNet = 1 // 0x80000001
// CoinTypeETH is ETH coin type
CoinTypeETH = 60 // 0x8000003c
// EmptyExtendedKeyString marker string for zero extended key
EmptyExtendedKeyString = "Zeroed extended key"
// MaxDepth is the maximum depth of an extended key.
// Extended keys with depth MaxDepth cannot derive child keys.
MaxDepth = 255
)
// errors
var (
ErrInvalidKey = errors.New("key is invalid")
ErrInvalidKeyPurpose = errors.New("key purpose is invalid")
ErrInvalidSeed = errors.New("seed is invalid")
ErrInvalidSeedLen = fmt.Errorf("the recommended size of seed is %d-%d bits", MinSeedBytes, MaxSeedBytes)
ErrDerivingHardenedFromPublic = errors.New("cannot derive a hardened key from public key")
ErrBadChecksum = errors.New("bad extended key checksum")
ErrInvalidKeyLen = errors.New("serialized extended key length is invalid")
ErrDerivingChild = errors.New("error deriving child key")
ErrInvalidMasterKey = errors.New("invalid master key supplied")
ErrMaxDepthExceeded = errors.New("max depth exceeded")
)
var (
// PrivateKeyVersion is version for private key
PrivateKeyVersion, _ = hex.DecodeString("0488ADE4")
// PublicKeyVersion is version for public key
PublicKeyVersion, _ = hex.DecodeString("0488B21E")
// EthBIP44ParentPath is BIP44 keys parent's derivation path
EthBIP44ParentPath = []uint32{
HardenedKeyStart + 44, // purpose
HardenedKeyStart + CoinTypeETH, // cointype set to ETH
HardenedKeyStart + 0, // account
0, // 0 - public, 1 - private
}
// EIP1581KeyTypeChat is used as chat key_type in the derivation of EIP1581 keys
EIP1581KeyTypeChat uint32 = 0x00
// EthEIP1581ChatParentPath is EIP-1581 chat keys parent's derivation path
EthEIP1581ChatParentPath = []uint32{
HardenedKeyStart + 43, // purpose
HardenedKeyStart + CoinTypeETH, // cointype set to ETH
HardenedKeyStart + 1581, // EIP-1581 subpurpose
HardenedKeyStart + EIP1581KeyTypeChat, // key_type (chat)
}
)
// ExtendedKey represents BIP44-compliant HD key
type ExtendedKey struct {
Version []byte // 4 bytes, mainnet: 0x0488B21E public, 0x0488ADE4 private; testnet: 0x043587CF public, 0x04358394 private
Depth uint8 // 1 byte, depth: 0x00 for master nodes, 0x01 for level-1 derived keys, ....
FingerPrint []byte // 4 bytes, fingerprint of the parent's key (0x00000000 if master key)
ChildNumber uint32 // 4 bytes, This is ser32(i) for i in xi = xpar/i, with xi the key being serialized. (0x00000000 if master key)
KeyData []byte // 33 bytes, the public key or private key data (serP(K) for public keys, 0x00 || ser256(k) for private keys)
ChainCode []byte // 32 bytes, the chain code
IsPrivate bool // (non-serialized) if false, this chain will only contain a public key and can only create a public key chain.
CachedPubKeyData []byte // (non-serialized) used for memoization of public key (calculated from a private key)
}
// nolint: gas
const masterSecret = "Bitcoin seed"
// NewMaster creates new master node, root of HD chain/tree.
// Both master and child nodes are of ExtendedKey type, and all the children derive from the root node.
func NewMaster(seed []byte) (*ExtendedKey, error) {
// Ensure seed is within expected limits
lseed := len(seed)
if lseed < MinSeedBytes || lseed > MaxSeedBytes {
return nil, ErrInvalidSeedLen
}
secretKey, chainCode, err := splitHMAC(seed, []byte(masterSecret))
if err != nil {
return nil, err
}
master := &ExtendedKey{
Version: PrivateKeyVersion,
Depth: 0,
FingerPrint: []byte{0x00, 0x00, 0x00, 0x00},
ChildNumber: 0,
KeyData: secretKey,
ChainCode: chainCode,
IsPrivate: true,
}
return master, nil
}
// Child derives extended key at a given index i.
// If parent is private, then derived key is also private. If parent is public, then derived is public.
//
// If i >= HardenedKeyStart, then hardened key is generated.
// You can only generate hardened keys from private parent keys.
// If you try generating hardened key form public parent key, ErrDerivingHardenedFromPublic is returned.
//
// There are four CKD (child key derivation) scenarios:
// 1) Private extended key -> Hardened child private extended key
// 2) Private extended key -> Non-hardened child private extended key
// 3) Public extended key -> Non-hardened child public extended key
// 4) Public extended key -> Hardened child public extended key (INVALID!)
func (k *ExtendedKey) Child(i uint32) (*ExtendedKey, error) {
if k.Depth == MaxDepth {
return nil, ErrMaxDepthExceeded
}
// A hardened child may not be created from a public extended key (Case #4).
isChildHardened := i >= HardenedKeyStart
if !k.IsPrivate && isChildHardened {
return nil, ErrDerivingHardenedFromPublic
}
keyLen := 33
seed := make([]byte, keyLen+4)
if isChildHardened {
// Case #1: 0x00 || ser256(parentKey) || ser32(i)
copy(seed[1:], k.KeyData) // 0x00 || ser256(parentKey)
} else {
// Case #2 and #3: serP(parentPubKey) || ser32(i)
copy(seed, k.pubKeyBytes())
}
binary.BigEndian.PutUint32(seed[keyLen:], i)
secretKey, chainCode, err := splitHMAC(seed, k.ChainCode)
if err != nil {
return nil, err
}
child := &ExtendedKey{
ChainCode: chainCode,
Depth: k.Depth + 1,
ChildNumber: i,
IsPrivate: k.IsPrivate,
// The fingerprint for the derived child is the first 4 bytes of parent's
FingerPrint: btcutil.Hash160(k.pubKeyBytes())[:4],
}
if k.IsPrivate {
// Case #1 or #2: childKey = parse256(IL) + parentKey
parentKeyBigInt := new(big.Int).SetBytes(k.KeyData)
keyBigInt := new(big.Int).SetBytes(secretKey)
keyBigInt.Add(keyBigInt, parentKeyBigInt)
keyBigInt.Mod(keyBigInt, btcec.S256().N)
// Make sure that child.KeyData is 32 bytes of data even if the value is represented with less bytes.
// When we derive a child of this key, we call splitHMAC that does a sha512 of a seed that is:
// - 1 byte with 0x00
// - 32 bytes for the key data
// - 4 bytes for the child key index
// If we don't padd the KeyData, it will be shifted to left in that 32 bytes space
// generating a different seed and different child key.
// This part fixes a bug we had previously and described at:
// https://medium.com/@alexberegszaszi/why-do-my-bip32-wallets-disagree-6f3254cc5846#.86inuifuq
keyData := keyBigInt.Bytes()
if len(keyData) < 32 {
extra := make([]byte, 32-len(keyData))
keyData = append(extra, keyData...)
}
child.KeyData = keyData
child.Version = PrivateKeyVersion
} else {
// Case #3: childKey = serP(point(parse256(IL)) + parentKey)
// Calculate the corresponding intermediate public key for intermediate private key.
keyx, keyy := btcec.S256().ScalarBaseMult(secretKey)
if keyx.Sign() == 0 || keyy.Sign() == 0 {
return nil, ErrInvalidKey
}
// Convert the serialized compressed parent public key into X and Y coordinates
// so it can be added to the intermediate public key.
pubKey, err := btcec.ParsePubKey(k.KeyData, btcec.S256())
if err != nil {
return nil, err
}
// childKey = serP(point(parse256(IL)) + parentKey)
childX, childY := btcec.S256().Add(keyx, keyy, pubKey.X, pubKey.Y)
pk := btcec.PublicKey{Curve: btcec.S256(), X: childX, Y: childY}
child.KeyData = pk.SerializeCompressed()
child.Version = PublicKeyVersion
}
return child, nil
}
// ChildForPurpose derives the child key at index i using a derivation path based on the purpose.
func (k *ExtendedKey) ChildForPurpose(p KeyPurpose, i uint32) (*ExtendedKey, error) {
switch p {
case KeyPurposeWallet:
return k.EthBIP44Child(i)
case KeyPurposeChat:
return k.EthEIP1581ChatChild(i)
default:
return nil, ErrInvalidKeyPurpose
}
}
// BIP44Child returns Status CKD#i (where i is child index).
// BIP44 format is used: m / purpose' / coin_type' / account' / change / address_index
// BIP44Child is depracated in favour of EthBIP44Child
// Param coinType is deprecated; we override it to always use CoinTypeETH.
func (k *ExtendedKey) BIP44Child(coinType, i uint32) (*ExtendedKey, error) {
return k.EthBIP44Child(i)
}
// BIP44Child returns Status CKD#i (where i is child index).
// BIP44 format is used: m / purpose' / coin_type' / account' / change / address_index
func (k *ExtendedKey) EthBIP44Child(i uint32) (*ExtendedKey, error) {
if !k.IsPrivate {
return nil, ErrInvalidMasterKey
}
if k.Depth != 0 {
return nil, ErrInvalidMasterKey
}
// m/44'/60'/0'/0/index
extKey, err := k.Derive(append(EthBIP44ParentPath, i))
if err != nil {
return nil, err
}
return extKey, nil
}
// EthEIP1581ChatChild returns the whisper key #i (where i is child index).
// EthEIP1581ChatChild format is used is the one defined in the EIP-1581:
// m / 43' / coin_type' / 1581' / key_type / index
func (k *ExtendedKey) EthEIP1581ChatChild(i uint32) (*ExtendedKey, error) {
if !k.IsPrivate {
return nil, ErrInvalidMasterKey
}
if k.Depth != 0 {
return nil, ErrInvalidMasterKey
}
// m/43'/60'/1581'/0/index
extKey, err := k.Derive(append(EthEIP1581ChatParentPath, i))
if err != nil {
return nil, err
}
return extKey, nil
}
// Derive returns a derived child key at a given path
func (k *ExtendedKey) Derive(path []uint32) (*ExtendedKey, error) {
var err error
extKey := k
for _, i := range path {
extKey, err = extKey.Child(i)
if err != nil {
return nil, ErrDerivingChild
}
}
return extKey, nil
}
// Neuter returns a new extended public key from a give extended private key.
// If the input extended key is already public, it will be returned unaltered.
func (k *ExtendedKey) Neuter() (*ExtendedKey, error) {
// Already an extended public key.
if !k.IsPrivate {
return k, nil
}
// Get the associated public extended key version bytes.
version, err := chaincfg.HDPrivateKeyToPublicKeyID(k.Version)
if err != nil {
return nil, err
}
// Convert it to an extended public key. The key for the new extended
// key will simply be the pubkey of the current extended private key.
return &ExtendedKey{
Version: version,
KeyData: k.pubKeyBytes(),
ChainCode: k.ChainCode,
FingerPrint: k.FingerPrint,
Depth: k.Depth,
ChildNumber: k.ChildNumber,
IsPrivate: false,
}, nil
}
// IsZeroed returns true if key is nil or empty
func (k *ExtendedKey) IsZeroed() bool {
return k == nil || len(k.KeyData) == 0
}
// String returns the extended key as a human-readable base58-encoded string.
func (k *ExtendedKey) String() string {
if k.IsZeroed() {
return EmptyExtendedKeyString
}
var childNumBytes [4]byte
binary.BigEndian.PutUint32(childNumBytes[:], k.ChildNumber)
// The serialized format is:
// version (4) || depth (1) || parent fingerprint (4)) ||
// child num (4) || chain code (32) || key data (33) || checksum (4)
serializedBytes := make([]byte, 0, serializedKeyLen+4)
serializedBytes = append(serializedBytes, k.Version...)
serializedBytes = append(serializedBytes, k.Depth)
serializedBytes = append(serializedBytes, k.FingerPrint...)
serializedBytes = append(serializedBytes, childNumBytes[:]...)
serializedBytes = append(serializedBytes, k.ChainCode...)
if k.IsPrivate {
serializedBytes = append(serializedBytes, 0x00)
serializedBytes = paddedAppend(32, serializedBytes, k.KeyData)
} else {
serializedBytes = append(serializedBytes, k.pubKeyBytes()...)
}
checkSum := chainhash.DoubleHashB(serializedBytes)[:4]
serializedBytes = append(serializedBytes, checkSum...)
return base58.Encode(serializedBytes)
}
// pubKeyBytes returns bytes for the serialized compressed public key associated
// with this extended key in an efficient manner including memoization as
// necessary.
//
// When the extended key is already a public key, the key is simply returned as
// is since it's already in the correct form. However, when the extended key is
// a private key, the public key will be calculated and memoized so future
// accesses can simply return the cached result.
func (k *ExtendedKey) pubKeyBytes() []byte {
// Just return the key if it's already an extended public key.
if !k.IsPrivate {
return k.KeyData
}
pkx, pky := btcec.S256().ScalarBaseMult(k.KeyData)
pubKey := btcec.PublicKey{Curve: btcec.S256(), X: pkx, Y: pky}
return pubKey.SerializeCompressed()
}
// ToECDSA returns the key data as ecdsa.PrivateKey
func (k *ExtendedKey) ToECDSA() *ecdsa.PrivateKey {
privKey, _ := btcec.PrivKeyFromBytes(btcec.S256(), k.KeyData)
return privKey.ToECDSA()
}
// NewKeyFromString returns a new extended key instance from a base58-encoded
// extended key.
func NewKeyFromString(key string) (*ExtendedKey, error) {
if key == EmptyExtendedKeyString || len(key) == 0 {
return &ExtendedKey{}, nil
}
// The base58-decoded extended key must consist of a serialized payload
// plus an additional 4 bytes for the checksum.
decoded := base58.Decode(key)
if len(decoded) != serializedKeyLen+4 {
return nil, ErrInvalidKeyLen
}
// The serialized format is:
// version (4) || depth (1) || parent fingerprint (4)) ||
// child num (4) || chain code (32) || key data (33) || checksum (4)
// Split the payload and checksum up and ensure the checksum matches.
payload := decoded[:len(decoded)-4]
checkSum := decoded[len(decoded)-4:]
expectedCheckSum := chainhash.DoubleHashB(payload)[:4]
if !bytes.Equal(checkSum, expectedCheckSum) {
return nil, ErrBadChecksum
}
// Deserialize each of the payload fields.
version := payload[:4]
depth := payload[4:5][0]
fingerPrint := payload[5:9]
childNumber := binary.BigEndian.Uint32(payload[9:13])
chainCode := payload[13:45]
keyData := payload[45:78]
// The key data is a private key if it starts with 0x00. Serialized
// compressed pubkeys either start with 0x02 or 0x03.
isPrivate := keyData[0] == 0x00
if isPrivate {
// Ensure the private key is valid. It must be within the range
// of the order of the secp256k1 curve and not be 0.
keyData = keyData[1:]
keyNum := new(big.Int).SetBytes(keyData)
if keyNum.Cmp(btcec.S256().N) >= 0 || keyNum.Sign() == 0 {
return nil, ErrInvalidSeed
}
} else {
// Ensure the public key parses correctly and is actually on the
// secp256k1 curve.
_, err := btcec.ParsePubKey(keyData, btcec.S256())
if err != nil {
return nil, err
}
}
return &ExtendedKey{
Version: version,
KeyData: keyData,
ChainCode: chainCode,
FingerPrint: fingerPrint,
Depth: depth,
ChildNumber: childNumber,
IsPrivate: isPrivate,
}, nil
}

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

52
vendor/github.com/status-im/status-go/extkeys/utils.go generated vendored Normal file
View File

@ -0,0 +1,52 @@
package extkeys
import (
"crypto/hmac"
"crypto/sha512"
"errors"
"math/big"
"github.com/btcsuite/btcd/btcec"
)
// errors
var (
ErrInvalidSecretKey = errors.New("generated secret key cannot be used")
)
func splitHMAC(seed, salt []byte) (secretKey, chainCode []byte, err error) {
data := hmac.New(sha512.New, salt)
if _, err = data.Write(seed); err != nil {
return
}
I := data.Sum(nil)
// Split I into two 32-byte sequences, IL and IR.
// IL = master secret key
// IR = master chain code
secretKey = I[:32]
chainCode = I[32:]
// IL (secretKey) is expected to be a 256-bit integer (it is used as parse256(IL)),
// and consequently that integer must be within range for SECP256k1 private key.
//
// There's tiny possibility (<1 in 2^127) this invariant is violated:
// error is returned in that case, and simple resolution is to request another child with i incremented.
keyBigInt := new(big.Int).SetBytes(secretKey)
if keyBigInt.Cmp(btcec.S256().N) >= 0 || keyBigInt.Sign() == 0 {
err = ErrInvalidSecretKey
}
return
}
// paddedAppend appends the src byte slice to dst, returning the new slice.
// If the length of the source is smaller than the passed size, leading zero
// bytes are appended to the dst slice before appending src.
// nolint: unparam
func paddedAppend(size uint, dst, src []byte) []byte {
for i := 0; i < int(size)-len(src); i++ {
dst = append(dst, 0)
}
return append(dst, src...)
}

5
vendor/modules.txt vendored
View File

@ -35,6 +35,9 @@ github.com/davidlazar/go-crypto/salsa20
github.com/deckarep/golang-set
# github.com/edsrzf/mmap-go v1.0.0
github.com/edsrzf/mmap-go
# github.com/elastic/gosigar v0.14.1
github.com/elastic/gosigar
github.com/elastic/gosigar/sys/windows
# github.com/ethereum/go-ethereum v1.10.4 => /home/cammellos/.go/src/github.com/status-im/go-ethereum
github.com/ethereum/go-ethereum
github.com/ethereum/go-ethereum/accounts
@ -468,6 +471,8 @@ github.com/status-im/migrate/v4/source/go_bindata
github.com/status-im/rendezvous
github.com/status-im/rendezvous/protocol
github.com/status-im/rendezvous/server
# github.com/status-im/status-go/extkeys v1.1.2
github.com/status-im/status-go/extkeys
# github.com/status-im/tcp-shaker v0.0.0-20191114194237-215893130501
github.com/status-im/tcp-shaker
# github.com/stretchr/testify v1.7.0