XSF logo XSF Discussion - 2018-12-31


  1. vanitasvitae I think I'm on a tagged version
  2. vanitasvitae Have to upgrade soon anyways ;D
  3. lovetox hm one moment
  4. lovetox what could also be is that the xml lib of dino prints this wrong
  5. lovetox but i guess less likely as it would have to happen with all stanzas then
  6. lovetox really weird bug
  7. efrit has left
  8. labdsf has left
  9. labdsf has joined
  10. edhelas has left
  11. edhelas has joined
  12. oli has joined
  13. oli has joined
  14. lnj has left
  15. thorsten has left
  16. UsL has left
  17. thorsten has joined
  18. UsL has joined
  19. oli has joined
  20. oli has joined
  21. Neustradamus It is possible to add new SCRAM in next XMPP Compliance Suites?
  22. lovetox has left
  23. efrit has joined
  24. waqas has left
  25. waqas has joined
  26. oli has left
  27. oli has left
  28. oli has joined
  29. waqas has left
  30. waqas has joined
  31. lumi has left
  32. waqas has left
  33. waqas has joined
  34. waqas has left
  35. waqas has joined
  36. waqas has left
  37. waqas has joined
  38. waqas has left
  39. waqas has joined
  40. dos has left
  41. pep. has left
  42. waqas has left
  43. waqas has joined
  44. waqas has left
  45. waqas has joined
  46. waqas has left
  47. waqas has joined
  48. waqas has left
  49. waqas has joined
  50. waqas has left
  51. waqas has joined
  52. lnj has left
  53. waqas has left
  54. waqas has joined
  55. waqas has left
  56. oli has joined
  57. lnj has left
  58. vanitasvitae has left
  59. lnj has joined
  60. Zash has left
  61. lnj has left
  62. ThibG has left
  63. ThibG has joined
  64. efrit has left
  65. edhelas has left
  66. alacer has joined
  67. moparisthebest has left
  68. Tobias has joined
  69. Tobias has joined
  70. MattJ has left
  71. moparisthebest has left
  72. ThibG has left
  73. ThibG has joined
  74. chunk has left
  75. chunk has joined
  76. ThibG has left
  77. ThibG has joined
  78. moparisthebest has joined
  79. moparisthebest has left
  80. Yagiza has joined
  81. moparisthebest has joined
  82. moparisthebest has left
  83. moparisthebest has left
  84. moparisthebest has left
  85. moparisthebest has left
  86. moparisthebest has joined
  87. Nekit has joined
  88. moparisthebest has joined
  89. Zash has left
  90. moparisthebest has left
  91. moparisthebest has joined
  92. moparisthebest has joined
  93. moparisthebest has left
  94. moparisthebest has left
  95. erkanfiles has left
  96. Nekit has left
  97. Nekit has joined
  98. chunk has left
  99. chunk has joined
  100. ThibG has joined
  101. ThibG has joined
  102. Yagiza has left
  103. sezuan has left
  104. waqas has joined
  105. alacer has left
  106. moparisthebest has joined
  107. lorddavidiii has joined
  108. frainz has left
  109. frainz has joined
  110. l has joined
  111. neshtaxmpp has left
  112. neshtaxmpp has left
  113. lorddavidiii has left
  114. lorddavidiii has joined
  115. oli has joined
  116. oli has left
  117. oli has left
  118. oli has joined
  119. lorddavidiii has left
  120. jjrh has left
  121. waqas has left
  122. Seve has left
  123. lorddavidiii has joined
  124. jjrh has left
  125. waqas has joined
  126. mrDoctorWho has joined
  127. oli has left
  128. oli has joined
  129. lovetox has joined
  130. alacer has joined
  131. genofire has left
  132. genofire has joined
  133. Wiktor > I thought "xmlns='urn:xmpp:bob'" would be illegal. Xml namespaces are URIs but practically any XML lib treats them as strings anyway (no validation). In your case the namespace is URN, colons are frequent in URNs :) (check out Wikipedia)
  134. moparisthebest has joined
  135. moparisthebest has joined
  136. waqas has left
  137. edhelas has joined
  138. alacer has left
  139. alacer has joined
  140. Yagiza has joined
  141. edhelas has left
  142. edhelas has joined
  143. waqas has joined
  144. alacer has left
  145. !xsf_Martin has joined
  146. edhelas has left
  147. edhelas has joined
  148. !xsf_Martin has left
  149. !xsf_Martin has joined
  150. !xsf_Martin has left
  151. edhelas has left
  152. edhelas has joined
  153. lskdjf has joined
  154. chunk has left
  155. marc_ has joined
  156. alacer has joined
  157. Yagiza has left
  158. daniel has joined
  159. waqas has left
  160. l has left
  161. l has joined
  162. Fahrgast has left
  163. Fahrgast has joined
  164. Fahrgast has left
  165. l has left
  166. l has joined
  167. vaulor has joined
  168. marc_ has left
  169. jonas’ huh
  170. jonas’ vanitasvitae, that bug sounds familiar
  171. jonas’ daniel, see above, I think you had the same thing the other day?
  172. Nekit has left
  173. Nekit has joined
  174. jonas’ vanitasvitae, what you’re seeing there sounds very much like what daniel had in https://github.com/siacs/Conversations/issues/3315
  175. jonas’ there seems to be some ejabberd bug there
  176. vanitasvitae jonas’: thanks for the link
  177. jonas’ Neustradamus, new SCRAM? what are you talking about?
  178. Guus has left
  179. efrit has joined
  180. vinx55 has joined
  181. l has joined
  182. l has joined
  183. l has joined
  184. lovetox SCRAM-256
  185. jonas’ are the weakened security properties of SHA-1 relevant for SCRAM?
  186. Zash Nope
  187. jonas’ then I don’t think it’s worth the trouble
  188. Zash Not that I know of at least
  189. Zash IIRC even HMAC-SHA1 is fine for things that HMACs are appropriate for
  190. lskdjf has joined
  191. Zash So yeah, combined with that you can't convert the hashes, it's not really worth it
  192. lovetox why was it then specified?
  193. jonas’ for new deployments probably
  194. Zash Hm?
  195. lovetox but why if it doesnt increase security
  196. jonas’ but in existing deployments, migrating the SCRAM version is a PITA -- you need a password change to achieve that
  197. jonas’ safe is better than sorry?
  198. lovetox hm not really convincing ..
  199. Zash Why use modern crypto?
  200. lovetox This document registers the SASL mechanisms SCRAM-SHA-256 and SCRAM- SHA-256-PLUS. SHA-256 has stronger security properties than SHA-1, and it is expected that SCRAM mechanisms based on it will have greater predicted longevity than the SCRAM mechanisms based on SHA-1.
  201. lovetox seems to be it does play indeed a role and is relevant
  202. Zash > SHA-256 has stronger security properties than SHA-1, This is true.
  203. Zash But whether that matters for how they are used in SCRAM is something different
  204. lovetox does not make much sense to specify a hash with great seurity properties, if you dont need these properties at all
  205. pep. Just like ipv6 was specified in the past, and still not used in the present, maybe someday in the future..
  206. Zash The real question is why not just wait for SCRAM-SHA-3
  207. jonas’ See [RFC4270] and [RFC6194] for reasons to move from SHA-1 to a strong security mechanism like SHA-256.
  208. jonas’ hah
  209. Zash What do they say?
  210. jonas’ TL;DR (yet)
  211. Zash Attacks on Cryptographic Hashes in Internet Protocols Ctrl-F "HMAC" - 0 matches
  212. jonas’ 3.3. HMAC-SHA-1 As of today, there is no indication that attacks on SHA-1 can be extended to HMAC-SHA-1.
  213. Zash lovetox: it's an improvement, but relatively small improvement.
  214. lovetox yeah probably :)
  215. jonas’ I’m composing a question on crypto.stackexchange about this
  216. Zash Remember that the state of the art before SCRAM was DIGEST-MD5 and storing plain text passwords.
  217. Zash DIGEST-MD5 -> SCRAM is a huge improvement all around
  218. Zash SCRAM-SHA-1 -> SCRAM-SHA-256 is a small improvement that would cost a lot for existing deployments
  219. mightyBroccoli has joined
  220. Zash Converting plain text passwords to hashed form is easy. Converting hashed form to a different hashed form is Hard
  221. alacer has left
  222. lovetox im not arguing for or against this new standard, it just was a contradiction to me that the ietf goes through the motion of making a new standard with a more expensive hash method, if it has no effect at all on security
  223. lovetox maybe it was "better save than sorry" but bringing such a standard to live seems to me a bit of work that nobody would do just because he feels like 256 is a prettier number
  224. Zash not no effect, it's better. but not enough better to outweight the cost of switching
  225. lovetox yeah you are probably right on that
  226. vinx55 has left
  227. lovetox it is though really easy to implement if you already have a SHA1 impl
  228. Zash depends
  229. Zash In theory it's just replacing the hash function
  230. Zash So if you have code that makes that easy then it's easy
  231. jonas’ there we go https://crypto.stackexchange.com/q/66195/16902
  232. rion has joined
  233. lovetox great writeup :)
  234. Zash There's one spot in SCRAM where it uses bare SHA-1 tho, for converting the ClientKey into StoredKey
  235. Zash StoredKey := H(ClientKey)
  236. jonas’ oh, I missed that
  237. jonas’ but storedkey is never transferred and only used as key in the hmac
  238. Zash But ClientKey is HMAC output and not combined with anything
  239. rion Does any XEP describe disco#info get requests with non-empty query element? Just found this in iris code w/o any reference to specs.
  240. oli has left
  241. oli has joined
  242. Zash rion: I think there's something like disco-subscriptions somewhere, but I'm not sure if there's a XEP
  243. oli has left
  244. rion I see xep-0230 but there is disco#items
  245. rion Ok, thanks Zash. I'll put it under #if 0 for now
  246. alacer has joined
  247. matlag has left
  248. lumi has joined
  249. lnj has joined
  250. UsL has left
  251. UsL has joined
  252. oli didn't we had the sha-256 discussion before? or was it at ejabberd?
  253. Zash has left
  254. daniel has left
  255. daniel has joined
  256. l has left
  257. chunk has left
  258. !xsf_Martin has joined
  259. chunk has joined
  260. MattJ has joined
  261. lskdjf has joined
  262. half-shot_ has joined
  263. rion has left
  264. Kev has joined
  265. ThibG has joined
  266. ThibG has joined
  267. Ge0rG has left
  268. !xsf_Martin has left
  269. !xsf_Martin has joined
  270. l has joined
  271. Ge0rG rion: IIRC it is also used in MIX to distinguish between MUC protocol and MIX protocol, but maybe it was disco#items as well
  272. jonas’ Ge0rG, no
  273. jonas’ MIX uses the node for that
  274. jonas’ *used
  275. jonas’ you confuse that with the roster query
  276. jonas’ so I’ve been thinking about MUC self ping. thinking about it, using a silent, non-archived <message/> might actually be the most traffic-efficient way to do it.
  277. Ge0rG jonas’: wasn't there disco#items on the MIX room JID to get a list of all nodes?
  278. Ge0rG jonas’: a message to whom?
  279. jonas’ Ge0rG, through the MUC
  280. jonas’ so to everyone, essentially
  281. Ge0rG jonas’: to the MUC?
  282. Ge0rG How's that more traffic efficient?
  283. jonas’ it is a ping for everyone. only one needs to send it, everyone else also learns that they themselves are still connected.
  284. jonas’ it is a ping for everyone. only one client needs to send it, everyone else also learns that they themselves are still connected.
  285. jonas’ so it saves sending the ping for everyone but one client.
  286. lorddavidiii has left
  287. jonas’ Ge0rG, MIX uses @node='mix' to qualify that; no need for child elements on the <{…disco#items}query/>
  288. jonas’ back to muc self-ping: if everyone implements it with "after N+random(-1, 1) minutes of no message received through the MUC, send a ping <message/>; if after N+M (M>2) minutes no message was received, conclude that we’re disconnected", the one with the lowest random() output will be the one who sends the pings, and everyone else silently benefits from it.
  289. jonas’ does that make sense?
  290. lovetox sounds weird, but somehow i like it
  291. lovetox wonder if this has any downsides
  292. Ge0rG jonas’: provided that we can normalize N. Also there might be minor inefficiency when multiple clients roll the same number. But I fear there will be clients making a short cut and not checking for the last incoming message, just sending anyway
  293. jonas’ potential downsides: if the MUC eats the <message/> (because it’s bodyless or whatever), it breaks. if the MUC archives the message, it pollutes the archive massively.
  294. jonas’ Ge0rG, slap those clients then.
  295. lovetox there are store hints for exactly that usecase
  296. lovetox and bodyless is no problem in any muc
  297. jonas’ lovetox, it may be with biboumi
  298. jonas’ but I think even biboumi simply reflects those on the XMPP side and drops them on the IRC side
  299. Ge0rG jonas’: but how is it better than the 0410 proposal?
  300. jonas’ Ge0rG, 1. it requires no server-side implementation; 2. in my specific implementation, it is easier to keep multiple <messages/> in flight and have a catch-all handler for the replies than with IQs (because IQs are request-response, and each in-flight IQ needs an entry in the response handler table -> memory use); 3. what happens when you send a message to a MUC you’re not joined to is more well-defined than IQ, 4. no race conditions with nickname changes or whatever
  301. lovetox the self ping has on its positive side that its easier to implement
  302. Ge0rG Also it might make sense to have different N for mobile vs desktop clients, and your suggestion ends up with `min(N) ` over all participants
  303. jonas’ (I don’t find it easier to implement, see (2) above)
  304. Ge0rG jonas’: some MUCs allow messages from non participants. What now?
  305. jonas’ Ge0rG, that’s a true point. For what it’s worth, a MUC implementation could still not forward the message to all participants but only reflect it to the sending client, if we find that it’s a battery hog.
  306. jonas’ Ge0rG, eh, why :D
  307. jonas’ I think with that, my proposal falls down the drain
  308. jonas’ good that we talked about it though
  309. Ge0rG jonas’: don't know why. Also some bridge implementations (looking at you, biboumi) will accept a message from a non joined resource of a joined user
  310. lovetox it is jonas in my opinion, one is just send an iq and wait for response, the other is, check messages for something then start a timer that i have to reset on the next message, and deal with over multiple scenarios like disconnect etc
  311. jonas’ lovetox, how long do you wait for a response for the IQ?
  312. lovetox lots of space to have bugs
  313. jonas’ no, you don’t need ot check messages for something
  314. jonas’ *every* message you receive lets you know you’re joined
  315. jonas’ you need that timer anyways if you want to implement self-ping efficiently.
  316. jonas’ you don’t need to send a ping when you just received a message from the MUC.
  317. lovetox hm yeah
  318. lovetox seems similar
  319. jonas’ (hint: the same thing goes for your main xml stream ;-))
  320. jonas’ problem with the IQ ping is the timeout
  321. jonas’ using a long timeout has the downside that if the MUC was temporarily blackholed, you have to wait very long until you can resync
  322. jonas’ using a short timeout has the downside that you won’t resync automatically in a high-latency situation.
  323. ThibG has joined
  324. jonas’ using multiple interleaved pings with long timeout has the memory cost issue
  325. Ge0rG jonas’: on timeout you should just mark the MUC as not responding, and schedule a new ping
  326. jonas’ Ge0rG, that’s obvious
  327. Ge0rG No need to have multiple interleaving pings
  328. jonas’ which timeout should I use for the ping then?
  329. lorddavidiii has joined
  330. lovetox i dont know what you are talking about memory, a timeout, compared to a full fletched gui client Oo
  331. jonas’ lovetox, aioxmpp might very well be used for a bot which runs ~forever and if it loses connectivity which isn’t restored, I don’t want it to turn into a memory hog
  332. jonas’ I don’t like ever-growing tables.
  333. jonas’ (and by "loses connectivity" I mean "a MUC in which it is joined becomes blackholed")
  334. Ge0rG jonas’: have a ping timeout of 60s and a ping interval of 10m after the last activity
  335. half-shot_ has left
  336. jonas’ Ge0rG, so if my link has a latency higher than 60s, I don’t ever resync to the MUC; it is "not responding" forever.
  337. Ge0rG jonas’: correct.
  338. jonas’ meh.
  339. Ge0rG Make it configurable for the military satellite use case
  340. jonas’ me not likey
  341. jonas’ lovetox, by the way, XEP-0410 even tells you to not self-ping unless the MUC is silent: > After an adequate amount of silence from a given MUC (e.g. 15 minutes), or from all MUCs from a given service domain, a client should initiate a self-ping.
  342. lovetox i just dont like timers, i pass a callback to some timer api, and later it comes back and bites me, either because the object for the callback is not there anymore, or because i forgot to cancel the timer if any of X events happen
  343. Ge0rG Yeah
  344. jonas’ which is why I wrapped this specific logic (which I already needed for the main xml stream anyways) in a class which takes care of handling the timer
  345. jonas’ I just should "nevermind, I got data!" at that class from time to time, and when I don’t do that, it’ll tell me "hey, no data for X time, wanna do something about that?"
  346. jonas’ I just shout "nevermind, I got data!" at that class from time to time, and when I don’t do that, it’ll tell me "hey, no data for X time, wanna do something about that?"
  347. Zash Prosody has something like that too.
  348. jonas’ so I can be reasonably confident that when that event triggers, something is wrong
  349. lovetox you just described a callback...
  350. lovetox i think we all know how this works
  351. jonas’ lovetox, typical callback APIs are a bit more convoluted than that though
  352. jonas’ (also, this has in fact two timers, a soft and a hard timeout)
  353. jonas’ you normally need to store some handle and exchange that whenever you re-set the timer
  354. jonas’ but that’s implementation details
  355. jonas’ I’m just saying one can make this rather painless
  356. !xsf_Martin has left
  357. !xsf_Martin has joined
  358. lovetox its painless if you have not many events that need the timer to be deleted, like an xml stream, what is there, essentially disconnect() thats the only event where you stop the timer
  359. jonas’ same goes for a MUC room. "leave" is the only thing where you stop the timer.
  360. lovetox think about chatstates, i have a inactive timer, it has to be reset whener the mouse moves over the window, if i switch the window, if i close the window, if i disconnect, etc this goes on and on
  361. lovetox but yeah, i see it depends on what you do with the timer
  362. lovetox :)
  363. thorsten has left
  364. marc_ has joined
  365. valo has joined
  366. valo has joined
  367. Yagiza has joined
  368. 404.city has joined
  369. jjrh has left
  370. vaulor has left
  371. vaulor has joined
  372. half-shot_ has joined
  373. chunk has left
  374. thorsten has joined
  375. tux has joined
  376. mimi89999 has joined
  377. half-shot_ has left
  378. lskdjf has joined
  379. lskdjf has left
  380. lskdjf has left
  381. genofire has left
  382. frainz has joined
  383. lskdjf has left
  384. lskdjf has left
  385. lskdjf has left
  386. lskdjf has left
  387. lskdjf has joined
  388. oli has left
  389. lskdjf has joined
  390. genofire has joined
  391. lskdjf has joined
  392. oli has left
  393. oli has left
  394. half-shot_ has joined
  395. half-shot_ has left
  396. half-shot_ has joined
  397. half-shot_ has left
  398. ta has left
  399. oli has left
  400. frainz has left
  401. oli has left
  402. frainz has joined
  403. genofire has left
  404. genofire has joined
  405. oli has joined
  406. lorddavidiii has left
  407. neshtaxmpp has joined
  408. moparisthebest has joined
  409. moparisthebest has joined
  410. genofire has left
  411. genofire has joined
  412. jjrh has left
  413. labdsf has left
  414. labdsf has joined
  415. genofire has left
  416. genofire has joined
  417. Zash has left
  418. Zash has left
  419. Zash has left
  420. lnj has left
  421. labdsf has left
  422. labdsf has joined
  423. mrDoctorWho has joined
  424. Yagiza has left
  425. Zash has left
  426. efrit has left
  427. genofire has left
  428. Guus has left
  429. jjrh has left
  430. jjrh has left
  431. Zash has left
  432. 404.city has left
  433. Yagiza has joined
  434. genofire has joined
  435. lnj has left
  436. Andrew Nenakhov has left
  437. Andrew Nenakhov has joined
  438. Andrew Nenakhov has left
  439. Andrew Nenakhov has joined
  440. oli has left
  441. lskdjf has left
  442. lovetox has left
  443. Neustradamus jonas’: https://tools.ietf.org/html/rfc7677 + https://tools.ietf.org/html/draft-ietf-mile-xmpp-grid-08
  444. lskdjf has left
  445. !xsf_Martin has left
  446. lskdjf has left
  447. lskdjf has left
  448. Marc Laporte has joined
  449. lnj has joined
  450. labdsf has left
  451. labdsf has joined
  452. labdsf has left
  453. labdsf has joined
  454. lnj has left
  455. Marc Laporte has left
  456. half-shot_ has joined
  457. moparisthebest has joined
  458. marc_ has left
  459. Steve Kille has left
  460. sezuan has left
  461. half-shot_ has left
  462. moparisthebest has joined
  463. Steve Kille has joined
  464. jjrh has left
  465. Maranda has left
  466. Maranda has joined
  467. jjrh has left
  468. jjrh has left
  469. Guus has left
  470. jjrh has left
  471. Neustradamus has left
  472. Neustradamus has joined
  473. Zash has left
  474. Zash has joined
  475. jjrh has left
  476. jjrh has left
  477. lnj has joined
  478. waqas has joined
  479. jjrh has left
  480. jjrh has left
  481. jjrh has left
  482. alacer has left
  483. UsL has left
  484. UsL has joined
  485. owl has joined
  486. pep. has left
  487. erkanfiles has joined
  488. erkanfiles has joined
  489. 404.city has joined
  490. igoose has left
  491. igoose has joined
  492. Nekit has left
  493. Nekit has joined
  494. alacer has joined
  495. marc_ has joined
  496. owl has left
  497. oli has left
  498. labdsf has left
  499. labdsf has joined
  500. Yagiza has left
  501. igoose has left
  502. igoose has joined
  503. lorddavidiii has joined
  504. marc_ has left
  505. jjrh has left
  506. jjrh has left
  507. 404.city has left
  508. waqas has left
  509. waqas has joined
  510. jjrh has left
  511. alacer has left
  512. neshtaxmpp has joined
  513. neshtaxmpp has left
  514. neshtaxmpp has left
  515. moparisthebest has joined
  516. neshtaxmpp has joined
  517. ThibG has left
  518. ThibG has joined
  519. lskdjf has left
  520. UsL has left
  521. UsL has joined
  522. mimi89999 has left
  523. lskdjf has left
  524. jjrh has left
  525. jjrh has left
  526. jjrh has left
  527. Nekit has joined
  528. Maranda has left
  529. oli has joined
  530. lskdjf has joined
  531. waqas has left
  532. waqas has joined
  533. oli has left
  534. oli has joined
  535. oli has left
  536. oli has joined
  537. oli has left
  538. oli has joined
  539. l has left
  540. APach has left
  541. oli has left
  542. oli has joined
  543. oli has left
  544. oli has joined
  545. oli has left
  546. oli has joined
  547. moparisthebest has joined
  548. oli has joined
  549. oli has joined
  550. oli has left
  551. oli has joined
  552. igoose has left
  553. oli has left
  554. oli has joined
  555. oli has left
  556. oli has joined
  557. lnj has left
  558. oli has left
  559. oli has joined
  560. oli has left
  561. oli has joined
  562. Maranda has joined
  563. thorsten has left
  564. igoose has joined
  565. oli has joined
  566. lorddavidiii has left
  567. oli has joined
  568. l has joined
  569. oli has left
  570. oli has joined
  571. oli has left
  572. oli has joined
  573. UsL has left
  574. UsL has joined
  575. vanitasvitae Happy new year!
  576. oli has left
  577. oli has joined
  578. pep. Happy public domain day
  579. jonas’ happy new year’s from CET https://sotecware.net/images/dont-puush-me/WVeQE5W9eDNjekWpVcI5J0z5i6kPBYXRJTHfxKQ_DF0.png
  580. jonas’ happy new year from CET https://sotecware.net/images/dont-puush-me/WVeQE5W9eDNjekWpVcI5J0z5i6kPBYXRJTHfxKQ_DF0.png
  581. oli has left
  582. oli has joined
  583. lskdjf has left
  584. MattJ has joined
  585. waqas pep.: I didn't realize that was a thing. Looks like "Yes! We Have No Bananas" is now in the public domain, https://www.youtube.com/watch?v=PDd8shcLvHI
  586. waqas There seems to be a list here: https://lifehacker.com/these-1923-copyrighted-works-enter-the-public-domain-in-1825241296
  587. lnj has joined
  588. Wiktor has left
  589. oli has left
  590. oli has joined
  591. moparisthebest has joined
  592. marc_ has joined
  593. oli has left
  594. oli has joined
  595. Seve Happy new year! :)
  596. oli has joined
  597. oli has joined
  598. l has left
  599. l has left
  600. l has left