Source of “help.html”.
819 lines, 33.4 KBytes.   Last modified 5:24 pm, 1st November 2015 PST.
1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html 4/strict.dtd"> 2 <html> 3 <!-- 4 5 //////////////////////////////////////////////////////////////////////////// 6 // // 7 // Pachylet: Andrew's Web Mail Interface, Version 2 // 8 // // 9 // Copyright (c) 2002-2015 // 10 // // 11 // Help file, help.html // 12 // // 13 //////////////////////////////////////////////////////////////////////////// 14 15 --> 16 17 <head> 18 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 19 <meta name="viewport" content="width=640"> 20 21 <style type="text/css"><!-- 22 23 A:link { color: #000099; } 24 A:active { color: #ff0000; } 25 A:visited { color: #000099; } 26 .noTouch A:hover { color: #006600; } 27 28 body { 29 background-color: #cccccc; 30 margin: 0px; 31 padding: 0px; 32 } 33 #helpDir, #helpBody { 34 position: absolute; 35 width: 40em; 36 left: 50%; 37 margin-left: -20em; 38 border: 1px #cccccc inset; 39 } 40 #helpDir { 41 z-index: 1; 42 border-style: solid; 43 line-height: 2; 44 } 45 #helpBody { 46 top: 0px; /* a placeholder, adjusted by the onload event */ 47 bottom: 0px; 48 overflow: auto; 49 -webkit-overflow-scrolling: touch; 50 background-color: #ffffff; 51 } 52 .helpSection { 53 padding: 0.5em; 54 display: none; 55 } 56 .helpDirBtn { 57 float: left; 58 width: 5em; 59 background-color: #6699cc; 60 } 61 .helpDirBtn a { 62 display: block; 63 border: 1px #cccccc inset; 64 white-space: nowrap; 65 font-size: 0.75em; 66 text-align: center; 67 } 68 .noTouch .helpDirBtn a:hover { 69 background-color: #88bbee; 70 } 71 .helpTitle { 72 font-size: 1.25em; 73 text-align: center; 74 margin-top: 0.4em; 75 margin-bottom: 0.8em; 76 } 77 .helpSection p, .helpSection ul, .helpSection table, .sourceCaveat { 78 margin-top: 1em; 79 margin-bottom: 0px; 80 } 81 sup { 82 vertical-align: top; 83 font-size: 0.6em; 84 } 85 div.elephant { 86 float: right; 87 background-color: #99cc99; 88 margin-left: 6px; 89 margin-bottom: 6px; 90 border: 2px #cccccc ridge; 91 padding: 12px; 92 } 93 img.elephant { 94 border-width: 0px; 95 } 96 .searchSample { 97 display: inline-block; 98 width: 12em; 99 font-family: monospace, courier, "courier new", lucida; 100 font-size: 13px; 101 } 102 .sourceListing { 103 display: inline-block; 104 width: 8em; 105 } 106 .sourceCaveat { 107 font-size: 0.75em; 108 } 109 @media screen and (max-device-width: 500px) { 110 #helpDir, #helpBody { 111 border-width: 0px; 112 } 113 #helpDir .helpDirBtn, .helpSection { 114 font-size: 2em; 115 } 116 #helpDir { 117 line-height: 2; 118 } 119 #searchSamples { 120 padding-left: 7em; 121 } 122 .searchSample { 123 position: absolute; 124 left: 0px; 125 padding: 0.5em; 126 width: 8em; 127 } 128 .sourceListing { 129 display: inline; 130 } 131 } 132 133 --> 134 </style> 135 136 <script type="text/javascript"><!-- 137 138 var pachyHelp = (function() { 139 140 var showing = null; 141 142 function show(id) { 143 var elt = document.getElementById(id); 144 if (showing) showing.style.display = "none"; 145 showing = elt; 146 showing.style.display = "block"; 147 document.getElementById("helpBody").scrollTop = 0; 148 if (history && history.replaceState) { 149 var stateObj = {}; 150 history.replaceState(stateObj, "", "#" + id); 151 } else { 152 location.hash = id; 153 } 154 return false; 155 } 156 157 function trumpet() { 158 // Play the elephant 159 // 160 document.getElementById("trumpet").play(); 161 return false; 162 } 163 164 function init() { 165 // Set helpBody position and size, and jump to appropriate section. 166 // 167 if (!("ontouchstart" in document.documentElement)) { 168 document.documentElement.className += " noTouch"; 169 } else { 170 document.documentElement.className += " touch"; 171 } 172 var dirHeight = document.getElementById("helpDir").offsetHeight; 173 var body = document.getElementById("helpBody"); 174 body.style.top = dirHeight + "px"; 175 var dest = (location.hash && location.hash != "" ? 176 location.hash.substring(1) : 177 null); 178 var elt; 179 if (dest && (elt = document.getElementById(dest)) && 180 elt.className == "helpSection") { 181 show(dest); 182 } else { 183 show("overview"); 184 } 185 } 186 187 return { 188 show: show, 189 trumpet: trumpet, 190 init: init 191 } 192 193 })(); // inline call of anonymous function 194 195 // --> 196 </script> 197 198 <title>Pachylet Documentation</title> 199 </head> 200 201 <body onload="pachyHelp.init()"> 202 203 <div style="display: none"> 204 <audio id=trumpet src="pachylet.au"></audio> 205 </div> 206 207 <div id=helpDir> 208 <div class=helpDirBtn><a href="#overview" 209 onClick="return pachyHelp.show('overview')">Overview</a></div> 210 <div class=helpDirBtn><a href="#simpleUse" 211 onClick="return pachyHelp.show('simpleUse')">Simple Use</a></div> 212 <div class=helpDirBtn><a href="#searching" 213 onClick="return pachyHelp.show('searching')">Searching</a></div> 214 <div class=helpDirBtn><a href="#smartFolders" 215 onClick="return pachyHelp.show('smartFolders')">Smart Folders</a></div> 216 <div class=helpDirBtn><a href="#composing" 217 onClick="return pachyHelp.show('composing')">Composing</a></div> 218 <div class=helpDirBtn><a href="#security" 219 onClick="return pachyHelp.show('security')">Security</a></div> 220 <div class=helpDirBtn><a href="#colophon" 221 onClick="return pachyHelp.show('colophon')">Colophon</a></div> 222 <div class=helpDirBtn><a href="#source" 223 onClick="return pachyHelp.show('source')">Source</a></div> 224 </div> <!-- helpDir --> 225 226 <div id=helpBody> 227 228 <div class=helpSection id=overview> 229 <div class=helpTitle>Overview</div> 230 <div class=elephant> 231 <a href="#" title="click to hear a Pachylet" 232 onclick="return pachyHelp.trumpet()"> 233 <img class=elephant src=pachylet.gif width=88 height=108 alt="A Pachylet"> 234 </a> 235 </div> 236 Pachylet is a web service for storing and accessing your email. It 237 retrieves your email from the Pachylet server itself, and from other 238 POP3 or IMAP mail servers on which you have accounts. It stores your 239 email in a database on the Pachylet server. You access your email from a 240 web browser running elsewhere. Nothing gets stored on your local 241 computer. 242 <p> 243 Pachylet has the traditional facilities for filing your email in 244 folders, moving it to a trash folder, and eventually deleting it. 245 However, it also has a very fast and powerful search mechanism, so you 246 can largely ignore the folders and just use the &ldquo;Drop&rdquo; 247 command to leave most of your email scattered around the single 248 &ldquo;Dropped&rdquo; folder, then find appropriate messages by 249 searching. 250 <p> 251 Additionally Pachylet provides &ldquo;smart folders&rdquo;, which let 252 you use searches to automatically pre-sort and filter your incoming 253 email. There&rsquo;s more description of all this later in this 254 document. 255 <p> 256 Pachylet tries to prevent malware intruding on your email through 257 attachments or through active HTML. Nevertheless, you should never open 258 an attachment unless you are certain that you trust the sender. You 259 should also be aware that if you view an HTML message by clicking on the 260 &ldquo;View as Web Page&rdquo; link, the images loaded there can 261 disclose information about your email usage. 262 <p> 263 Pachylet works on all modern web browsers, including most smart phones. 264 See the &ldquo;Colophon&rdquo; section of this page for details of the 265 various versions. 266 <p> 267 Pachylet was written by me, <a 268 href="http://birrell.org/andrew/me/">Andrew Birrell</a>, and is 269 copyright &copy; 2002-2014. All rights reserved. You may use Pachylet 270 only on this server, and you do so entirely at your own risk. There is 271 no warranty whatsoever. 272 </div> 273 274 <div class=helpSection id=simpleUse> 275 <div class=helpTitle>Simple Use</div> 276 While you can use Pachylet in the traditional manner (filing important 277 messages carefully and systematically, and then deleting the rest) the 278 user interface encourages a different style, which I recommend that you 279 try: 280 <ul> 281 <li>When a message arrives, most likely you should click 282 &ldquo;Drop&rdquo;. This places the message into a special 283 &ldquo;Dropped&rdquo; folder. Only if you&rsquo;re certain that you 284 never ever want to see the message again, click &ldquo;Trash&rdquo; 285 instead (this omits the message from search results, unless 286 you explicitly search in the &ldquo;Trash&rdquo folder. 287 <li>Subsequently, to find a message, click &ldquo;Find&rdquo; and type a 288 few words from the message. Most likely you&rsquo;ll find the message 289 you want quickly. 290 <li>In rare cases, you can use &ldquo;Move&rdquo; to move or copy a 291 message into a folder, so that you can find it again without using the 292 full-text search facilities of &ldquo;Find&rdquo;. 293 <li>Use &ldquo;smart folders&rdquo; to pre-sort your incoming messages 294 (described below). These let you categorize the messages automatically, 295 and the &ldquo;Scan&rdquo; button then lets you view them in their 296 categorized order. 297 298 </ul> 299 <p> 300 The normal Javascript version of the user interface does most of its 301 interactions with the Pachylet server asynchronously, so that you 302 don&rsquo;t have to wait for the server to respond. For example, after 303 you&rsquo;ve clicked to select a message, you can file that message 304 somewhere, or select a different message, without waiting for the 305 message contents to arrive on your screen. 306 <p> 307 The user interface is designed so that you can process your incoming 308 messages with the central buttons &ldquo;Next&rdquo;, 309 &ldquo;Drop&rdquo;, &ldquo;Trash&rdquo; and &ldquo;Scan&rdquo;. 310 Occasionally, you&rsquo;ll use &ldquo;Move&rdquo;, and as appropriate 311 you&rsquo;ll generate replies. 312 <p> 313 The &ldquo;Find&rdquo; button lets you do a general search (described 314 below). &ldquo;Scan&rdquo; works its way through your unread messages 315 that have arrived in your smart folders. &ldquo;Folders&rdquo; lets you 316 view and manage your folders, be they normal or smart. 317 <p> 318 Messages that have been moved to the Trash folder can be permanently 319 deleted: open the Trash folder, select the message, and click the 320 &ldquo;Delete&rdquo; button. 321 <p> 322 In the version for smart phones, these buttons are organized 323 differently. Also there, there are no features for creating or deleting 324 folders or smart folders, or for permanently deleting messages. 325 </div> 326 327 <div class=helpSection id=searching> 328 <div class=helpTitle>Searching</div> 329 The &ldquo;Find&rdquo; button lets you search for messages. A search 330 usually produces its results very quickly, so it&rsquo;s easy to try 331 different search queries. The same queries get used in creating smart 332 folders, described in the next section. 333 <p> 334 A search takes place within a folder (normal or smart), or across 335 everything except the Trash folder. You describe the messages you want 336 to find by giving some combination of words from the messages and date 337 ranges. You can restrict the word search to the message header, or some 338 of its fields. 339 <p> 340 By default, the &ldquo;Find&rdquo; dialog is set up to show the query 341 you made most recently (or the folder you opened). If you want to ignore 342 that and search elsewhere, click &ldquo;Clear&rdquo; in the 343 &ldquo;Find&rdquo; dialog. 344 <p> 345 The text you search for in the &ldquo;Find&rdquo; command is actually a 346 potentially elaborate expression in a search language (defined by the 347 &ldquo;Sphinx&rdquo; search engine). The possibilities include: 348 <p id=searchSamples> 349 <span class=searchSample>quick fox</span> 350 &hellip; contains 351 both &ldquo;quick&rdquo; and &ldquo;fox&rdquo; 352 <br> 353 <span class=searchSample>quick | fox</span> 354 &hellip; contains 355 either &ldquo;quick&rdquo; or &ldquo;fox&rdquo;, or both 356 <br> 357 <span class=searchSample>quick -fox</span> 358 &hellip; contains 359 &ldquo;quick&rdquo; but not &ldquo;fox&rdquo; 360 <br> 361 <span class=searchSample>"quick brown"</span> 362 &hellip; contains 363 &ldquo;quick&rdquo; immediately followed by &ldquo;brown&rdquo; 364 <br> 365 <span class=searchSample>qui*</span> 366 &hellip; contains 367 a word that begins with the letters &ldquo;qui&rdquo; 368 <br> 369 <span class=searchSample>(quick brown) | fox</span> 370 &hellip; contains 371 both &ldquo;quick&rdquo; and &ldquo;brown&rdquo;, 372 or contains &ldquo;fox&rdquo; 373 <br> 374 <span class=searchSample>quick brown | fox</span> 375 &hellip; contains 376 &ldquo;quick&rdquo; and either &ldquo;brown&rdquo; or &ldquo;fox&rdquo; 377 <p> 378 A &ldquo;word&rdquo; is a sequence of letters, digits, and 379 &ldquo;_&rdquo;; letter case is ignored. Many other characters have 380 special meanings, and you should either avoid them or read <a 381 href="http://sphinxsearch.com/docs/current.html#extended-syntax">the 382 full documentation</a>. 383 <p> 384 The results of a search are presented sorted by date, and positioned to 385 the most recent. That means it&rsquo;s usually fine to have the search 386 criteria be quite loose, because you probably want the most recent 387 messages. If you don&rsquo;t want the most recent messages, then the 388 date range options in &ldquo;Find&rdquo; should help you. 389 </div> 390 391 <div class=helpSection id=smartFolders> 392 <div class=helpTitle>Smart Folders</div> 393 Smart folders serve multiple purposes. They are the most powerful, and 394 the most complex, feature of Pachylet. A smart folder is a real folder: 395 you can move messages into or out of a smart folder just as you can with 396 a normal folder. But a smart folder also has an associated query, 397 that&rsquo;s saved permanently with your Pachylet data. 398 <p> 399 The most common use of a smart folder is to pre-sort or filter your 400 incoming messages. Whenever Pachylet receives new mail, the messages are 401 matched against the queries of your smart folders. When a new message 402 matches a smart folder&rsquo;s query, the message is moved into that 403 folder. The only messages that appear in your Inbox are those that match 404 none of your smart folders&rsquo; queries. 405 <p> 406 This would be unhelpful without the &ldquo;Scan&rdquo; button on the 407 main screen. This button searches your smart folders sequentially, 408 checking for unread messages. 409 <p> 410 The net effect when new messages arrive is that they get sorted into 411 your smart folders and your Inbox, then the &ldquo;Scan&rdquo; button 412 lets you view them sequentially, in this sorted order. The user 413 interface is arranged such that if you click &ldquo;Scan&rdquo; and get 414 to a folder that you don&rsquo;t want to read right now, you can ignore 415 it (by clicking the button again, or by doing something else) without 416 disturbing it. 417 <p> 418 A secondary use of smart folders is to filter your messages. When you 419 create or edit a smart folder, there&rsquo;s an option to mark matching 420 incoming messages as having been read. This means they are ignored by 421 &ldquo;Scan&rdquo;. For example, you can use this to move bcc copies of 422 messages from yourself into a &ldquo;Sent&rdquo; folder that 423 you&rsquo;ll never see unless you explicitly open it. 424 <p> 425 The final use of smart folders has nothing to do with folders. When you 426 use the &ldquo;Folders&rdquo; button to see your folders, in the smart 427 folders section there&rsquo;s a &ldquo;Find&rdquo; button. This finds 428 messages matching the selected smart folder&rsquo;s query, regardless of 429 whether they are currently in the folder. It&rsquo;s a way to keep a 430 query that you use frequently, such as &ldquo;messages dated within the 431 last month&rdquo;. (This feature isn&rsquo;t implemented on iPhone.) 432 </div> 433 434 <div class=helpSection id=composing> 435 <div class=helpTitle>Composing Messages</div> 436 The &ldquo;Compose&rdquo;, &ldquo;Forward&rdquo;, &ldquo;To 437 Author&rdquo;, and &ldquo;To All&rdquo; buttons create a new draft 438 message. You edit the draft to suit, then click &ldquo;Send&rdquo; or 439 &ldquo;Discard&rdquo;. 440 <p> 441 The most recent state of an in-progress draft is held entirely in your 442 web browser, but it can be saved to the Pachylet server. In the 443 Javascript versions (including the iPhone version), this happens 444 automatically within 30 seconds of an edit. In the non-script version, 445 you need to manually click &ldquo;Save&rdquo; (which you can also do in 446 the other versions, if you feel you need to). 447 <p> 448 Having saved the draft (automatically or manually), you can safely move 449 away from the composition window (click &ldquo;Done&rdquo; or 450 &ldquo;Back&rdquo; in the Javascript versions, or close the window in 451 the non-script version). The draft remains in your &ldquo;Unsent&rdquo; 452 folder, and you can resume composition by clicking on it there. 453 <p> 454 To add an attachment to a message in the non-iPhone javascript version, 455 click the &ldquo;Attach&rdquo;, choose the file, then click 456 &ldquo;Attach&rdquo; in the dialog. In the non-script version, jusy 457 choose the file and click &ldquo;save&rdquo;. There&rsquo;s no way to 458 add an attachment in the iPhone version. 459 <p> 460 Pachylet includes a contacts list. You can manage this manually by 461 clicking &ldquo;Contacts&rdquo; on the main screen, or you can add a 462 name from an incoming message by clicking the &ldquo;keep&rdquo; link 463 beside the name. (Neither of these is available on the iPhone version.) 464 <p> 465 You can add a recipient from your contacts list to a current draft by 466 typing the recipient&rsquo;s first or last name (or both), or the 467 recipient&rsquo;s nickname, into the &ldquo;to&rdquo; or 468 &ldquo;cc&rdquo; fields. In the non-iPhone Javascript version you can 469 see and search your contacts list in the side pane on the composition 470 screen. Add a recipient by clicking on a contact in that list. In the 471 iPhone version this is available by clicking the &ldquo;Add&rdquo; 472 button. In the non-script version you can browse your contacts list by 473 clicking &ldquo;Contacts&rdquo; in the composition window. 474 </div> 475 476 <div class=helpSection id=security> 477 <div class=helpTitle>Security</div> 478 All versions of the Pachylet client use an encrypted (TLS) connection 479 for all interactions with the server. This guarantees that all data is 480 sent to and comes from the server, without it being visible to a third 481 party outside of the client or server. However, it&rsquo;s up to you to 482 verify that you are actually using the correct server name with an HTTPS 483 URL, by looking at your browser&rsquo;s address bar. 484 <p> 485 You log in to Pachylet on its login screen by providing your user name 486 and password. The server compares these to a salted hash of the 487 password, stored in its database. If they match, your client is sent a 488 &ldquo;cookie&rdquo;, which it uses to authenticate you on subsequent 489 requests to the server. Generally, you should log out when you are 490 finished using Pachylet. When you logout, the server makes the client 491 destroy the cookie. 492 <p> 493 On desktop or laptop browsers, the authentication cookie is destroyed 494 when you exit from the browser application. On mobile devices like an 495 iPhone or iPad the cookie remains on the device for about a week, 496 allowing you to use Pachylet again without typing your password again. 497 This assumes that your mobile device is protected by a lock screen with 498 a non-trivial PIN or password. 499 <p> 500 Your plain-text password is never stored in stable storage, only a 501 secure salted hash of it. 502 <p> 503 If you care, you can read <a href="#securityDetails" 504 onClick="return pachyHelp.show('securityDetails')">technical details</a> 505 of Pachylet&rsquo;s security design. 506 </div> 507 508 <div class=helpSection id=securityDetails> 509 <div class=helpTitle>Security: Technical Details</div> 510 All communication between the browser and the Pachylet server occurs over 511 TLS (using HTTPS). The Pachylet server is configured to prefer cipher 512 suites that have "forward secrecy", if supported by your browser (true 513 for all modern browsers). The forward secrecy property is effective after 514 a week (when the server generates a new TLS session token key). 515 <p> 516 There are five values for each user, all intended to be secret: 517 <ul> 518 <li>the plain-text password, typed into the UI; 519 <li>a derived key, which is a salted hash of the plain-text password; 520 <li>H1, a hash of the derived key, stored in the server&rsquo;s file system; 521 <li>H2, a separate hash of the derived key; 522 <li>a hash of H2, stored in the MySQL database. 523 </ul> 524 <p> 525 At login, the client sends the plain-text password to the Pachylet 526 server over a TLS connection. The server computes the derived key, and 527 the hashes H1 and H2. The login is authenticated by comparing the 528 computed H1 with the value stored in the file system. The computed H2 is 529 presented to MySQL as the MySQL connection password. MySQL computes its 530 hash of H2 and compares it to the stored value. On success, the server 531 returns the derived key to the client as a cookie. The cookie is 532 presented to the server on subsequent operations, and again used to 533 authenticate the login and to connect to MySQL. When the user logs out, 534 the server causes the client to erase the cookie. 535 <p> 536 Additionally, H2 is used to encrypt third-party passwords stored for the 537 user in the database. These are the passwords that will be used to 538 fetch the user&rsquo;s email from various POP and IMAP servers. This 539 encryption reduces the impact of an intruder who can read the database. 540 <p> 541 The plain-text password is never stored in stable storage, and is erased 542 from the UI and discarded as soon as possible. The derived key is 543 computed from the plain-text password by the PBKDF2 algorithm, using 544 100,000 iterations, a 128-bit random salt (from /dev/urandom), and 545 HMAC-SHA256 to yield a 256-bit derived key. These parameters, including 546 the chosen salt, are stored in the server&rsquo;s file system. The 547 derived key is never stored in stable storage on the server. H1 and H2 548 are computed using HMAC-SHA256 on separate (constant) strings, signed 549 with the derived key. The hash value stored by MySQL for its login is 550 &ldquo;sha1(sha1(H2))&rdquo;. The derived-key cookie is flagged 551 &ldquo;secure&rdquo; and &ldquo;HTTP only&rdquo; and isn&rsquo;t 552 accessible to the client JavaScript. On desktop and laptop machines, 553 the cookie is per-session and is destroyed when you exit from the web 554 browser application. On mobile devices like iPhone, iPad, or Android 555 tablets, the cookie persists for one week. This assumes that have 556 reasonable PIN or password protection for access to your mobile device. 557 The third-party passwords inside the database are encrypted using RC4 558 keyed by a random 128-bit IV hashed together with the derived key; the 559 first 4096 bytes of the RC4 key stream are discarded. 560 <p> 561 If the user&rsquo;s plain-text password has a decent level of entropy, 562 such as 60 bits, then it is economically infeasible to acquire the 563 plain-text password from the derived key by brute force. It is 564 equally difficult to acquire the 256-bit derived key from H1, H2, or 565 the MySQL hashed key; or to acquire H2 from the MySQL hashed key. 566 <p> 567 Aside from the obvious goal of allowing access only to authenticated 568 users, there are secondary goals related to how badly a compromise of 569 the system will hurt. 570 <p> 571 There are a few extreme possibilities. First, if the user&rsquo;s 572 device is compromised, then the user&rsquo;s login identity including 573 the plain-text password is unavoidably compromised. Second, if an 574 intruder gains root access to the server, then all subsequent use of the 575 server is compromised. Third, if an intruder can modify the scripts or 576 programs used by the server, then all subsequent use of the server is 577 compromised. Note, however, that the user&rsquo;s plain-text password 578 is compromised only if it is used while the device or server compromise 579 is in effect, not earlier: we have perfect forward secrecy in that 580 sense. (This is assuming the absence of attacks on the TLS connection, 581 which might or might not have perfect forward secrecy.) 582 <p> 583 For lesser attacks, we have two secondary goals. First, an attack on 584 the server must not allow the attacker to determine the user&rsquo;s 585 plain-text password, because it is most likely related to passwords for 586 that user elsewhere. Assuming the integrity of the server&rsquo;s 587 programs, the derived key machinery accomplishes this. Second, an attack 588 that permits read-only access to privileged areas of the server must not 589 be permitted to escalate into read-write access. This is achieved 590 because the hash stored by MySQL cannot be used to acquire H2 or the 591 derived key; and because H1 cannot be used to aquire the derived key. 592 Finally, observe that H2 is useful only within the server; access from 593 the web requires the derived key. (There is no network access to the 594 MySQL server.) 595 <p> 596 We shouldn&rsquo;t allow server-side scripts free access to the H1 597 stored in the file system. Partly, this is because we would prefer to 598 keep H1 secret. But more importantly, the Pachylet server-side scripts 599 are no more privileged than any other server-side script: if we allow 600 the Pachylet scripts to modify the stored H1 directly (e.g., to allow a 601 user to change their password), then any other server-side script could 602 also modify H1 and enable network login. This still would not enable 603 access to the MySQL database, but this attack could be combined with 604 some other attack to do so. Therefore we restrict all access to the 605 stored H1 file to a more privileged user, and provide a setuid 606 application that allows the requisite operations only to a script that 607 knows the matching derived key. 608 <p> 609 However, we weaken this scheme in two ways. 610 <p> 611 First, we retain H2 in stable storage on the server. Reading this would 612 allow an on-server program to acquire read-write access to the database. 613 We do this to allow a periodic job to be run that incorporates new mail 614 for the user while the user is offline. The stored H2 is in a file that 615 is readable only to root, and is given only to a script protected as 616 well as the server&rsquo;s other application programs and scripts. Hence 617 an intruder can read the stored H2 only if the server is already fully 618 compromised. Note that even if H2 is revealed, it allows no access from 619 the web, and the user&rsquo;s plain-text password is not compromised. 620 <p> 621 Second, we maintain on the server a publicly readable file for each user, 622 containing the number of unread messages for that user. This allows 623 unauthenticated &ldquo;new mail&rdquo; indications, for example on some 624 other web page. 625 <p> 626 This design doesn&rsquo;t use a separate &ldquo;session ID&rdquo;. This 627 is primarily because the server maintains no per-session state. Having 628 a separate session ID would add complexity and gain us no useful 629 functionality. Tangentially, note that we can revoke a derived key and 630 H2 at any time by changing the user&rsquo;s &ldquo;salt&rdquo; value and 631 computing a new H1 and H2. This happens, for example, whenever the user 632 informs the server of a new plain-text password, even if the new 633 password is equal to the previous password. 634 <p> 635 Not all of the user&rsquo;s data is stored in the database. Message 636 parts (main body, alternative bodies, or attachments) larger than 10,000 637 bytes are stored in the file system, although the first 10,000 bytes are 638 also stored in the database for use by the full-text indexing system. 639 These files are accessible equally to any script running in the server. 640 We encrypt the part files, using a key stored for the part in the 641 database. Each part uses a different key, derived from the H2 hash and 642 the part&rsquo;s unique ID. The key is retained in the database for each 643 part to avoid re-encryption when the user changes their password. The 644 encryption is done with AES-256 in CBC mode with PKCS #7 block padding. 645 There is a single fixed IV (which is OK, because each part file uses a 646 different key). A MAC of the plain text is stored in the database. The 647 MAC is computed with HMAC-SHA-256, keyed with the part&rsquo;s key. The 648 decryption function computes a MAC even if the block padding is 649 incorrect, to avoid padding-oracle timing attacks. This design is 650 intended to make the part files as secure as the database itself. The 651 only additional vulnerability is denial of service by deleting a part 652 file. 653 <p> 654 No security design would be complete without some arrangement for 655 auditing what the system actually does. We do this by writing log 656 entries whenever the client-side scripts do anything substantial (using 657 the &ldquo;syslog&rdquo; machinery). The server sends a daily summary 658 of these log entries to the system administrator. 659 <p> 660 Finally, note that the server must protect itself from many other 661 attacks. SQL injection attacks are avoided if the server is careful to 662 escape all arbitrary strings received from the client or from other 663 servers; cross-site-scripting attacks need similar protection. To 664 prevent cross-site request forgery attacks, the server insists that all 665 incoming requests, including the login request, have an HTTP 666 &ldquo;referer&rdquo; header line that references a page on the same 667 machine and in the same directory as the server script, served by HTTPS. 668 </div> 669 670 <div class=helpSection id=colophon> 671 <div class=helpTitle>Colophon</div> 672 The name &ldquo;Pachylet&rdquo; is reminiscent of 673 &ldquo;Pachyderm&rdquo;, an animal rumoured to never forget your email. 674 See also the <a 675 href="http://web.archive.org/web/19980123212517/http://www.research.digital. com/SRC/pachyderm/" >Pachyderm 676 web site</a> or a <a 677 href="http://birrell.org/andrew/talks/pachyderm.pdf">Pachyderm talk</a>, 678 both from 1997. 679 <p> 680 There are three client-side versions: 681 <ul> 682 <li>&ldquo;V1&rdquo; uses static HTML generated by a server-side script. 683 <li>&ldquo;V2&rdquo; is an &ldquo;AJAX&rdquo; web application using 684 Javacript, designed for the desktop. 685 <li>Pachylet Mobile is designed for smart phones. 686 </ul> 687 <p> 688 The web pages generated by the V1 client are very simple, and 689 don&rsquo;t rely on any client-side scripting. They should work on any 690 recent browser, even with Javascript disabled. They do require CSS 691 support, and they won&rsquo;t work on ancient browsers like IE4. 692 <p> 693 The V2 client and Pachylet Mobile use caching and asynchronous 694 communication to remove a lot of the latency in communicating with the 695 server, producing dramatically better performance. They also transfers 696 much less data from the server (important on slow or expensive 697 connections). In exchange, they needs a modern browser. V2 requires IE 698 10 or later, Safari 8 or later, or pretty much any version of Firefox or 699 Chrome. V2 also works, a bit awkwardly, in the Kindle&rsquo;s browser. 700 Pachylet Mobile should be fine with iOS 8 or later, or any iPad or 701 Android. I currently debug on IE10 on Windows 7, Chrome 44 on Android, 702 Safari 8 on MacOS 10.10.4, Firefox 38 on MacOS 10.10.4, and iOS 8 on 703 iPhone. 704 </div> 705 706 <div class=helpSection id=source> 707 <div class=helpTitle>Source Code</div> 708 <div class=sourceCaveat> 709 Note that Pachylet is a copyright work. You may read the sources for 710 educational purposes, but you are not allowed to use them elsewhere, nor 711 to make derived works. Any use you make of these files is entirely at 712 your own risk. There is no warranty whatsoever. 713 </div> 714 <p> 715 The V2 (AJAX) client (about 6200 lines): 716 <ul> 717 <li><a class=sourceListing 718 href="lister.php?file=pachyletV2.html">pachyletV2.html</a> 719 &hellip; The basic HTML page 720 <li><a class=sourceListing 721 href="lister.php?file=pachyletV2.css">pachyletV2.css</a> 722 &hellip; CSS Stylesheet 723 <li><a class=sourceListing 724 href="lister.php?file=pachyletV2.php">pachyletV2.php</a> 725 &hellip; Server-side PHP script 726 <li><a class=sourceListing 727 href="lister.php?file=pachyletV2.js">pachyletV2.js</a> 728 &hellip; Client-side Javascript 729 <li><a class=sourceListing 730 href="lister.php?file=common.js">common.js</a> 731 &hellip; Client-side Javascript library 732 </ul> 733 <p> 734 Pachylet Mobile (about 2100 lines, layered on the regular V2 client): 735 <ul> 736 <li><a class=sourceListing 737 href="lister.php?file=iphone.html">iphone.html</a> 738 &hellip; The basic HTML page 739 <li><a class=sourceListing 740 href="lister.php?file=iphone.css">iphone.css</a> 741 &hellip; CSS Stylesheet 742 <li><a class=sourceListing 743 href="lister.php?file=iphone.js">iphone.js</a> 744 &hellip; Client-side Javascript 745 <li><a class=sourceListing 746 href="lister.php?file=iphoneManifest.php">iphoneManifest.php</a> 747 &hellip; Script to generate the HTML 5 manifest file 748 <li><a class=sourceListing 749 href="lister.php?file=manifest-php.txt">manifest-php.txt</a> 750 &hellip; Library code for generating an HTML 5 manifest 751 </ul> 752 <p> 753 The V1 (static HTML) client (about 3200 lines): 754 <ul> 755 <li><a class=sourceListing 756 href="lister.php?file=pachyletV1.php">pachyletV1.php</a> 757 &hellip; Server-side PHP script 758 <li><a class=sourceListing 759 href="lister.php?file=pachyletV1.css">pachyletV1.css</a> 760 &hellip; CSS stylesheet 761 <li><a class=sourceListing 762 href="lister.php?file=pachyletV1.js">pachyletV1.js</a> 763 &hellip; Client-side Javascript (can be disabled) 764 <li><a class=sourceListing 765 href="lister.php?file=pachymgmt.php">pachymgmt.php</a> 766 &hellip; Administrative access to Pachylet accounts 767 </ul> 768 <p> 769 Client-independent code (about 5000 lines): 770 <ul> 771 <li><a class=sourceListing 772 href="lister.php?file=index.php">index.php</a> 773 &hellip; Top-level switcher between iPhone and non-iPhone 774 <li><a class=sourceListing 775 href="lister.php?file=pachysql.php">pachysql.php</a> 776 &hellip; MySQL access and handling labels and message parts 777 <li><a class=sourceListing 778 href="lister.php?file=pachyauth.php">pachyauth.php</a> 779 &hellip; Library for the Pachylet authentication scheme 780 <li><a class=sourceListing 781 href="lister.php?file=pachyhash.c">pachyhash.c</a> 782 &hellip; A setuid program to manage the H1 hash files 783 <li><a class=sourceListing 784 href="lister.php?file=pachylib.php">pachylib.php</a> 785 &hellip; Mostly inc, send and account settings 786 <li><a class=sourceListing 787 href="lister.php?file=pachyparts.php">pachyparts.php</a> 788 &hellip; Page for displaying attachments or HTML message bodies 789 <li><a class=sourceListing 790 href="lister.php?file=pachyparts2.php">pachyparts2.php</a> 791 &hellip; Page for acquiring a password for pachyparts.php 792 <li><a class=sourceListing 793 href="lister.php?file=detached.html">detached.html</a> 794 &hellip; Page for viewing a message in a separate window 795 <li><a class=sourceListing 796 href="lister.php?file=help.html">help.html</a> 797 &hellip; The documentation 798 <li><a class=sourceListing 799 href="lister.php?file=create.txt">create.txt</a> 800 &hellip; SQL commands for creating a Pachylet account 801 <li><a class=sourceListing 802 href="lister.php?file=delete.txt">delete.txt</a> 803 &hellip; SQL commands for deleting a Pachylet account 804 <li><a class=sourceListing 805 href="lister.php?file=pachyinc.php">pachyinc.php</a> 806 &hellip; Script for incorporating mail into Pachylet from cron 807 <li><a class=sourceListing 808 href="lister.php?file=mailcheck.php">mailcheck.php</a> 809 &hellip; Reports &ldquo;new mail&rdquo; status 810 <li><a class=sourceListing 811 href="lister.php?file=lister.php">lister.php</a> 812 &hellip; The source listing program 813 </ul> 814 </div> 815 816 </div> 817 818 </body> 819 </html>
End of listing