user.iced 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679
  1. req = require './req'
  2. db = require './db'
  3. {constants} = require './constants'
  4. {chain_err,make_esc} = require 'iced-error'
  5. {GE,E} = require './err'
  6. deepeq = require 'deep-equal'
  7. {SigChain} = require './sigchain'
  8. log = require './log'
  9. {UntrackerProofGen,TrackerProofGen} = require './sigs'
  10. {session} = require './session'
  11. {env} = require './env'
  12. {TrackWrapper} = require './trackwrapper'
  13. {fpeq,unix_time} = require('pgp-utils').util
  14. {QuarantinedKeyRing,TmpKeyRing,load_key,master_ring} = require './keyring'
  15. {athrow,akatch} = require('iced-utils').util
  16. IS = constants.import_state
  17. {PackageJson} = require('./package')
  18. libkeybase = require 'libkeybase'
  19. tor = require './tor'
  20. colors = require './colors'
  21. kbpgp = require 'kbpgp'
  22. {merkle_client} = require './merkle_client'
  23. ##=======================================================================
  24. filter = (d, v) ->
  25. out = {}
  26. for k in v when d?
  27. out[k] = d[k]
  28. return out
  29. ##=======================================================================
  30. exports.User = class User
  31. #--------------
  32. @cache : {}
  33. @server_cache : {}
  34. @FIELDS : [ "basics", "public_keys", "id", "merkle_data", "private_keys", "logged_in" ]
  35. #--------------
  36. constructor : (args) ->
  37. for k in User.FIELDS
  38. @[k] = args[k]
  39. @_dirty = false
  40. @sig_chain = null
  41. @_is_self = false
  42. @_have_secret_key = false
  43. @sibkeys = []
  44. @gpg_keys = []
  45. #--------------
  46. set_logged_in : () -> @logged_in = session.logged_in()
  47. #--------------
  48. set_is_self : (b) -> @_is_self = b
  49. is_self : () -> @_is_self
  50. set_have_secret_key : (b) -> @_have_secret_key = b
  51. have_secret_key : -> @_have_secret_key
  52. #--------------
  53. to_obj : () ->
  54. out = {}
  55. for k in User.FIELDS
  56. out[k] = @[k]
  57. return out
  58. #--------------
  59. private_key_bundle : () -> @private_keys?.primary?.bundle
  60. #--------------
  61. names : () ->
  62. ret = [ { type : constants.lookups.username, name : @basics.username } ]
  63. if (ki64 = @key_id_64())?
  64. ret.push { type : constants.lookups.key_id_64_to_user, name : ki64 }
  65. if (fp = @fingerprint false)?
  66. ret.push { type : constants.lookups.key_fingerprint_to_user, name : fp }
  67. return ret
  68. #--------------
  69. store : (force_store, cb) ->
  70. err = null
  71. un = @username()
  72. if force_store or @_dirty
  73. log.debug "+ #{un}: storing user to local DB"
  74. await db.put { key : @id, value : @to_obj(), names : @names() }, defer err
  75. log.debug "- #{un}: stored user to local DB"
  76. if @sig_chain? and not err?
  77. log.debug "+ #{un}: storing signature chain"
  78. await @sig_chain.store defer err
  79. log.debug "- #{un}: stored signature chain"
  80. cb err
  81. #--------------
  82. update_fields : (remote) ->
  83. for k in User.FIELDS
  84. @update_field remote, k
  85. true
  86. #--------------
  87. update_field : (remote, which) ->
  88. if not (deepeq(@[which], remote[which]))
  89. @[which] = remote[which]
  90. @_dirty = true
  91. #--------------
  92. load_sig_chain_from_storage : (cb) ->
  93. err = null
  94. log.debug "+ load sig chain from local storage"
  95. if (ph = @merkle_data?.payload_hash)?
  96. log.debug "| loading sig chain w/ payload hash #{ph}"
  97. await SigChain.load @id, @username(), ph, defer err, @sig_chain
  98. else
  99. log.debug "| No payload hash tail pointer found"
  100. @sig_chain = new SigChain @id, @username()
  101. log.debug "- loaded sig chain from local storage"
  102. cb err
  103. #--------------
  104. load_full_sig_chain : (cb) ->
  105. log.debug "+ load full sig chain"
  106. sc = new SigChain @id, @username()
  107. await sc.update null, defer err
  108. @sig_chain = sc unless err?
  109. log.debug "- loaded full sig chain"
  110. cb err
  111. #--------------
  112. update_sig_chain : (remote_seqno, cb) ->
  113. log.debug "+ update sig chain; remote_seqno=#{remote_seqno}"
  114. await @sig_chain.update remote_seqno, defer err, did_update
  115. if did_update
  116. last = @sig_chain.last().export_to_user()
  117. log.debug "| update sig_chain last link to #{JSON.stringify last}"
  118. @_dirty = true
  119. log.debug "- updated sig chain"
  120. cb err
  121. #--------------
  122. update_with : (remote, cb) ->
  123. err = null
  124. log.debug "+ updating local user w/ remote"
  125. a = @basics?.id_version
  126. b = remote?.basics?.id_version
  127. if not b? or a > b
  128. err = new E.VersionRollbackError "Server version-rollback suspected: Local #{a} > #{b}"
  129. else
  130. # Always update fields, irrespective of whether the id_version has
  131. # actually increased, because the server format might've changed.
  132. @update_fields remote
  133. if not err?
  134. await @update_sig_chain remote.merkle_data?.seqno, defer err
  135. log.debug "- finished update"
  136. cb err
  137. #--------------
  138. @map_key_to_user_local : (query, cb) ->
  139. log.debug "+ map_key_to_user_local #{JSON.stringify query}"
  140. err = ret = null
  141. await db.lookup query, defer err, row
  142. k = JSON.stringify query
  143. if err? then # noop
  144. else if not row?
  145. err = new E.NotFoundError "Key not found for query #{k}"
  146. else
  147. b = row.basics
  148. ret = { uid : b.uid, username : b.username }
  149. log.debug "- map_key_to_user_local -> #{err}"
  150. cb err, ret
  151. #--------------
  152. @map_key_to_user : (query, cb) ->
  153. log.debug "+ map_key_to_user: #{JSON.stringify query}"
  154. await User.map_key_to_user_local query, defer err, basics
  155. await User.map_key_to_user_remote query, defer err, basics if err?
  156. log.debug "- mapped -> #{err}"
  157. cb err, basics
  158. #--------------
  159. @map_key_to_user_remote : (query, cb) ->
  160. qs = JSON.stringify query
  161. log.debug "+ #{qs}: map to username"
  162. err = null
  163. L = constants.lookups
  164. body = null
  165. key = switch query.type
  166. when L.key_fingerprint_to_user then 'fingerprint'
  167. when L.key_id_64_to_user then 'pgp_key_id'
  168. else
  169. err = new E.BadQueryError "Bad query type: #{query.type}"
  170. null
  171. unless err?
  172. d = {}
  173. d[key] = query.name
  174. req_args =
  175. endpoint : "key/basics"
  176. args : d
  177. await req.get req_args, defer err, body
  178. log.debug "- #{qs}: map -> #{err}"
  179. cb err, body
  180. #--------------
  181. @load : ({username,ki64,require_public_key, cache, self, secret}, cb) ->
  182. err = null
  183. if username? and (ret = User.cache[username])?
  184. log.debug "| hit user cache for #{username}"
  185. else
  186. await User._load2 { username, ki64, require_public_key, cache, self, secret}, defer err, ret
  187. cb err, ret
  188. #--------------
  189. @_load2 : ({username,ki64,require_public_key, cache, self, secret}, cb) ->
  190. esc = make_esc cb, "User::load"
  191. k = if username? then username else "Key: #{ki64}"
  192. log.debug "+ #{username}: load user"
  193. await User.load_from_storage {username,ki64}, esc defer local
  194. # If we need to, get the new username
  195. if not username? then username = local?.basics?.username
  196. if self and secret and not tor.strict()
  197. log.debug "| Checking session since we're loading User as self (and need secret key)"
  198. await session.load_and_check esc defer()
  199. if (self and tor.strict())
  200. log.warn "Tor strict mode: #{colors.bold('not')} syncing your profile with the server"
  201. else
  202. fetched_from_server = true
  203. await User.load_from_server {self, secret, username, local_user: local}, esc defer remote
  204. changed = true
  205. force_store = false
  206. if local?
  207. user = local
  208. if remote?
  209. await user.update_with remote, esc defer()
  210. else if remote?
  211. user = remote
  212. await user.load_full_sig_chain esc defer()
  213. force_store = true
  214. else if tor.strict()
  215. err = new E.TorStrictError "Can't load your info from the server in strict Tor mode"
  216. else
  217. err = new E.NotFoundError "User #{username} wasn't found"
  218. await athrow err, esc defer() if err?
  219. if require_public_key and not user.merkle_data?.eldest_kid?
  220. await athrow new Error("user doesn't have a public key"), esc defer()
  221. if not user.public_keys?.all_bundles?
  222. await athrow new Error("User key bundles missing."), esc defer()
  223. await libkeybase.ParsedKeys.parse { key_bundles: user.public_keys.all_bundles }, esc defer parsed_keys
  224. # Verify the user's sigchain, even if it's empty. This at least checks
  225. # ownership of an eldest PGP key.
  226. # TODO: Enable verification caching.
  227. log.debug "+ #{username}: verifying signatures"
  228. await user._verify {parsed_keys, self}, esc defer()
  229. log.debug "- #{username}: verified signatures"
  230. # If we fetched from the server, store the new data to disk.
  231. if fetched_from_server
  232. await user.store force_store, esc defer()
  233. log.debug "- #{username}: loaded user"
  234. # Cache in some cases...
  235. User.cache[username] = user if cache and not err? and user?
  236. cb err, user
  237. #--------------
  238. @load_from_server : ({self, secret, username, local_user}, cb) ->
  239. esc = make_esc cb, "User::load_from_server"
  240. log.debug "+ #{username}: load user from server"
  241. # If we've loaded the user before in this process, the result is cached in
  242. # memory. Short circuit and return that.
  243. if (ret = User.server_cache[username])?
  244. log.debug "| hit server cache"
  245. cb null, ret
  246. return
  247. # Load the user's Merkle tip.
  248. await merkle_client().find_and_verify {username}, esc defer leaf, root, server_id_version
  249. # If the user's Merkle leaf exists (meaning they have an eldest key at all,
  250. # i.e. not a newly-created empty user), check it against past Merkle tree
  251. # data and maybe short circuit.
  252. local_id_version = local_user?.basics?.id_version
  253. local_seqno = local_user?.merkle_data?.seqno
  254. if leaf?
  255. pub = leaf.get_public()
  256. server_seqno = pub?.seqno
  257. if (server_id_version == local_id_version and
  258. server_seqno == local_seqno and
  259. local_user._format_up_to_date {})
  260. # Nothing new to load. Short-circuit.
  261. log.debug "| id_version (#{local_id_version}) and seqno (#{local_seqno}) haven't changed."
  262. cb null, null
  263. return
  264. else if server_id_version < local_id_version
  265. cb new Error("Server id version (#{server_id_version}) rolled back from local (#{local_id_version})")
  266. return
  267. else if server_seqno < local_seqno
  268. cb new Error("Server seqno (#{server_seqno}) rolled back from local (#{local_seqno})")
  269. return
  270. if pub?
  271. seqno = pub.seqno
  272. # The Merkle tree gives a short sig_id. Add the common suffix.
  273. sig_id = pub.sig_id + libkeybase.SIG_ID_SUFFIX
  274. payload_hash = pub.payload_hash
  275. merkle_data = {
  276. seqno,
  277. sig_id,
  278. payload_hash,
  279. eldest_kid: leaf.get_eldest_kid()
  280. }
  281. else
  282. # No Merkle leaf exists, because user has no key history.
  283. merkle_data = null
  284. # Load the full user from the server.
  285. args =
  286. endpoint : "user/lookup"
  287. args : {username }
  288. need_cookie : (self and secret)
  289. await req.get args, esc defer body
  290. ret = new User body.them
  291. ret.set_logged_in()
  292. # Attach merkle-tree info to the user. This will get saved when we store
  293. # the user on disk.
  294. ret.merkle_data = merkle_data
  295. User.server_cache[username] = ret
  296. log.debug "- #{username}: loaded user from server"
  297. cb null, ret
  298. #--------------
  299. _format_up_to_date : ({}) ->
  300. # Check for new server fields that might be missing in old cached data.
  301. if not @public_keys?.all_bundles?
  302. return false
  303. return true
  304. #--------------
  305. @load_from_storage : ({username, ki64}, cb) ->
  306. name = username or ki64
  307. log.debug "+ #{name}: load user from local storage"
  308. type = if username? then constants.lookups.username else constants.lookups.key_id_64_to_user
  309. await db.lookup { type, name }, defer err, row
  310. if not err? and row?
  311. ret = new User row
  312. await ret.load_sig_chain_from_storage defer err
  313. if err?
  314. ret = null
  315. log.debug "- #{name}: loaded user from local storage -> #{err} / #{ret}"
  316. cb err, ret
  317. #--------------
  318. fingerprint : (upper_case = false) ->
  319. unless @_fingerprint?
  320. @_fingerprint =
  321. lc : @default_key()?.fingerprint().toString('hex')
  322. @_fingerprint.uc = @_fingerprint.lc?.toUpperCase()
  323. return @_fingerprint[if upper_case then 'uc' else 'lc']
  324. #--------------
  325. key_id_64 : () ->
  326. if (fp = @fingerprint false)? then fp[-16...] else null
  327. #--------------
  328. #
  329. # @resolve_user_name
  330. #
  331. # Given a username like reddit://maxtaco or fingerprint://aa99ee or keybase://max,
  332. # resolve to a regular keybase username, like max.
  333. #
  334. @resolve_user_name : ({username}, cb) ->
  335. log.debug "+ resolving username #{username}"
  336. esc = make_esc cb, "resolve_user_name"
  337. err = null
  338. await akatch (() -> libkeybase.assertion.URI.parse { s : username, strict : false }), esc defer uri
  339. unless uri.is_keybase()
  340. await req.get { endpoint : "user/lookup", args : uri.to_lookup_query() }, esc defer body
  341. if body.them.length is 0
  342. err = new E.NotFoundError "No user found for '#{username}'"
  343. else if body.them.length > 1
  344. err = new E.AmbiguityError "Multiple results returned for '#{username}'; expected only 1"
  345. else
  346. username = body.them[0].basics.username
  347. ass_out = uri
  348. log.debug "- resolved to #{username}"
  349. cb err, username, ass_out
  350. #--------------
  351. #
  352. # load_me
  353. #
  354. # Loads the me user from some combination of the server and local storage.
  355. # The me user can be loaded with or without a secret key, depending on the opts,
  356. # but a public key is required.
  357. #
  358. # @param {Object} opts the load options
  359. # @option {Bool} opts.secret whether to load the secret key or not.
  360. # @option {Bool} opts.install_key whether to install a key if it wasn't found
  361. # @param {Callback} cb Callback with an `<Error,User>` pair, with error set
  362. # on failure, and null on success.
  363. #
  364. @load_me : (opts, cb) ->
  365. esc = make_esc cb, "User::load_me"
  366. log.debug "+ User::load_me"
  367. unless (username = env().get_username())?
  368. await athrow (new E.NoUsernameError "no username for current user; try `keybase login`"), esc defer()
  369. await User.load { username, self : true, secret : opts.secret }, esc defer me
  370. await me._load_me_2 opts, esc defer()
  371. log.debug "- User::load_me"
  372. cb null, me
  373. #--------------
  374. _load_me_2 : ({secret, maybe_secret, install_key, verify_opts }, cb) ->
  375. esc = make_esc cb, "User::_load_me_2"
  376. un = @username()
  377. @set_is_self true
  378. # If the user has no keys at all, short-circuit.
  379. if @sibkeys.length == 0
  380. cb null
  381. return
  382. load_secret = secret or maybe_secret
  383. if load_secret
  384. await master_ring().make_secret_gpg_key_from_user {user: @}, defer err, @key
  385. else
  386. # Just pick one available public key, for backwards compatibility.
  387. @key = @default_key()
  388. log.debug "+ #{un}: checking public key"
  389. await @key.find defer err
  390. log.debug "- #{un}: checked public key"
  391. if not err? and load_secret
  392. @set_have_secret_key true
  393. else if err? and (err instanceof E.NoLocalKeyError) and maybe_secret
  394. # Fall back to same as above.
  395. @key = @default_key()
  396. log.debug "+ #{un}: checking public key"
  397. await @key.find defer err
  398. log.debug "- #{un}: checked public key"
  399. if err? and (err instanceof E.NoLocalKeyError) and install_key
  400. do_install = true
  401. else if err?
  402. await athrow err, esc defer()
  403. else
  404. do_install = false
  405. if do_install
  406. await @key.commit {}, esc defer()
  407. cb null
  408. #--------------
  409. # Checks to see if the user has the key locally or remotely.
  410. check_key : ({secret, store}, cb) ->
  411. ret = {}
  412. log.debug "+ #{@username()}: check public key"
  413. if @fingerprint()?
  414. ret.remote = (not(secret) or @private_key_bundle()?)
  415. if secret
  416. await master_ring().make_secret_gpg_key_from_user {user: @}, defer err, key
  417. else
  418. key = @default_key()
  419. await key.find defer err
  420. if not err?
  421. ret.local = true
  422. @key = key if store
  423. else if (err instanceof E.NoLocalKeyError)
  424. err = null
  425. ret.local = false
  426. log.debug "- #{@username()}: check_public_key: ret=#{JSON.stringify ret}; err=#{err}"
  427. cb err, ret
  428. #--------------
  429. load_public_key : ({signer}, cb) ->
  430. log.debug "+ load public key for #{@username()}"
  431. err = null
  432. unless @key?
  433. query = { username : @username(), fingerprint : @fingerprint() }
  434. await load_key query, defer err, @key
  435. log.debug "- load public key; found=#{!!@key}; err=#{err}"
  436. cb err, @key
  437. #--------------
  438. username : () -> @basics.username
  439. #--------------
  440. import_public_keys : ({keyring}, cb) ->
  441. esc = make_esc cb, "User::import_public_keys"
  442. log.debug "+ Import public keys from #{keyring.to_string()}"
  443. for key in @gpg_keys
  444. await key.save esc defer()
  445. log.debug "- Import public keys from #{keyring.to_string()}"
  446. cb null
  447. #--------------
  448. display_cryptocurrency_addresses : (opts, cb) ->
  449. await @sig_chain.display_cryptocurrency_addresses opts, defer err
  450. cb err
  451. #--------------
  452. check_remote_proofs : (opts, cb) ->
  453. opts.gpg_keys = @gpg_keys
  454. opts.username = @username()
  455. await @sig_chain.check_remote_proofs opts, defer err, warnings, n_proofs
  456. cb err, warnings, n_proofs
  457. #--------------
  458. # Also serves to compress the public signatures into a usable table.
  459. _verify : ({opts, parsed_keys, self}, cb) ->
  460. esc = make_esc cb, "User::verify"
  461. @sibkeys = []
  462. @gpg_keys = []
  463. # If there is no eldest key, then this is a new account or it just did a
  464. # total account reset. Short-circuit.
  465. if not @merkle_data?.eldest_kid?
  466. cb null
  467. return
  468. # Verify the chain!
  469. # XXX: In the one case of a KeyOwnershipError for the user's *own*
  470. # sigchain, suppress the error. This can come up if you've uploaded a PGP
  471. # key that doesn't include your identity in it, but you haven't signed any
  472. # links yet. This is a tricky case to get right, so make sure to think
  473. # about it / test it when changing this code.
  474. await @sig_chain.verify_sig { opts, @key, parsed_keys, @merkle_data }, defer err, @sibkeys
  475. if err?
  476. if self and (err instanceof libkeybase.E.KeyOwnershipError)
  477. log.warn "You have not proven ownership of your key. Run `keybase push --update`."
  478. @sibkeys = [parsed_keys.get_merged_pgp_key_manager @merkle_data.eldest_kid]
  479. else
  480. cb err
  481. return
  482. @gpg_keys = master_ring().make_all_public_gpg_keys_from_user {user: @}
  483. cb null
  484. #--------------
  485. # BACKWARDS COMPATIBILITY for parts of the code that still think there's only
  486. # one key.
  487. default_key : () ->
  488. @gpg_keys[0]
  489. #--------------
  490. list_remote_proofs : (opts) -> @sig_chain?.list_remote_proofs(opts)
  491. list_trackees : () -> @sig_chain?.list_trackees()
  492. list_cryptocurrency_addresses : () -> @sig_chain?.list_cryptocurrency_addresses()
  493. merkle_root : () -> @sig_chain?.merkle_root_to_track_obj()
  494. #--------------
  495. gen_remote_proof_gen : ({klass, remote_name_normalized, sig_id, supersede }, cb) ->
  496. arg = {
  497. remote_name_normalized,
  498. sig_id,
  499. supersede
  500. }
  501. await @gen_sig_base { klass, arg }, defer err, ret
  502. cb err, ret
  503. #--------------
  504. gen_sig_base : ({klass, arg}, cb) ->
  505. ret = null
  506. await @load_public_key {}, defer err
  507. unless err?
  508. arg.eldest_kid = @merkle_data.eldest_kid
  509. arg.km = @key
  510. arg.merkle_root = @merkle_root()
  511. arg.client = (new PackageJson()).track_obj()
  512. ret = new klass arg
  513. cb err, ret
  514. #--------------
  515. gen_track_proof_gen : ({uid, track_obj, untrack_obj}, cb) ->
  516. last_link = @sig_chain?.true_last()
  517. klass = if untrack_obj? then UntrackerProofGen else TrackerProofGen
  518. arg =
  519. seqno : (if last_link? then (last_link.seqno() + 1) else 1)
  520. prev : (if last_link? then last_link.id else null)
  521. uid : uid
  522. arg.track = track_obj if track_obj?
  523. arg.untrack = untrack_obj if untrack_obj?
  524. await @gen_sig_base { klass, arg }, defer err, ret
  525. cb err, ret
  526. #--------------
  527. gen_track_obj : () ->
  528. pkp = @public_keys.primary
  529. out =
  530. basics : filter @basics, [ "id_version", "last_id_change", "username" ]
  531. id : @id
  532. key :
  533. kid : @merkle_data?.eldest_kid
  534. seq_tail : @sig_chain?.true_last()?.to_track_obj()
  535. remote_proofs : @sig_chain?.remote_proofs_to_track_obj()
  536. ctime : unix_time()
  537. out
  538. #--------------
  539. remove_key : (cb) ->
  540. esc = make_esc cb, "User::remove_key"
  541. for key in @gpg_keys
  542. await key.remove esc defer()
  543. cb null
  544. #--------------
  545. gen_untrack_obj : () ->
  546. pkp = @public_keys.primary
  547. out =
  548. basics : filter @basics, [ "id_version", "last_id_change", "username" ]
  549. id : @id
  550. key : filter pkp, [ "kid", "key_fingerprint" ]
  551. out
  552. ##=======================================================================