Compare commits

..

309 Commits

Author SHA1 Message Date
d3cb0ab3f6 0.4.1
Checked in late, forgot to do so after actual release
2015-09-28 12:16:31 +00:00
e5fa4706db Fix loading of user guide and FAQ translations (#1641) 2015-09-12 15:40:16 +00:00
ecdd2ee426 Added new user guide translation 2015-09-12 14:30:22 +00:00
784a716f0a Updated translations 2015-09-12 14:29:53 +00:00
afdde691b4 CME fix 2015-09-02 01:33:49 +00:00
65d9439e03 Add owner to new ticket URL 2015-08-23 05:59:08 +00:00
8d19c4c78a Fixed CME 2015-08-21 02:22:35 +00:00
8731a72887 0.4 2015-08-21 02:20:25 +00:00
9e1b42134c Remove build numbers from version 2015-08-21 02:20:02 +00:00
17b4d035eb Update last checked time for manual checks too 2015-08-20 23:58:49 +00:00
d967d50c51 Fix email checking 2015-08-20 23:50:17 +00:00
42770cf01b Updated ignores 2015-08-20 11:53:10 +00:00
c910e17f6c Fix bug with sending anon emails 2015-08-20 11:52:09 +00:00
d408242173 Test OutboxProcessor.sendEmail(), proves existence of bug with anon emails 2015-08-20 11:26:34 +00:00
c52429f393 Add Mockito to unittest deps 2015-08-20 11:24:58 +00:00
aac9df446f 0.3 2015-08-15 23:33:58 +00:00
da40d97185 Temporarily disable IMAP due to class loader issues
Apache Commons Logging can't find the Log4J classes, because (I think) it is
not looking in the plugin's class loader (the classes are visible in I2P-Bote).
2015-08-15 23:23:51 +00:00
e661e4306c Updated ignores 2015-08-15 02:09:45 +00:00
18005cdfb3 Updated translations 2015-08-15 02:01:58 +00:00
1a7e8daf8e Fix app icon so it is bundled 2015-08-15 01:58:23 +00:00
771153c4d7 Add app icon 2015-08-15 01:55:14 +00:00
f1e750cef1 Change author to me (for feedback) 2015-08-15 01:54:54 +00:00
52e30278b5 Bump min I2P version to 0.9.18 (first to include my SU3 plugin cert) 2015-08-15 01:44:51 +00:00
4f1b81510f Add SU3 update URL 2015-08-15 01:32:26 +00:00
0c4d1dc5c3 Changed plugin signer and update URL 2015-08-15 01:28:38 +00:00
c1934b4576 Added missing image 2015-08-15 01:27:32 +00:00
0edd014c6b Deduplicate dependency verification 2015-08-15 01:26:47 +00:00
27e02ce527 Fix connection checking 2015-08-14 01:30:55 +00:00
9aa14a705e Only show "Check email" button for identities when connected 2015-08-14 00:56:50 +00:00
219de6e499 Adjust identities column widths on old themes 2015-08-14 00:56:19 +00:00
d07f790dbb Fix NPE in identity creation by properly saving identity config 2015-08-13 23:35:00 +00:00
8abfc8345b Deduplication 2015-08-13 12:39:37 +00:00
3cbcfaa331 Add config option for including local deps in update
Local deps are now moved out of update, because with the impending change of
plugin signer, all users will have all current JARs.
2015-08-13 12:00:06 +00:00
63b63a9f65 Bugfix 2015-08-13 11:29:42 +00:00
29f5db767d Extract common packing macro, delete .jar files from plugin (JIC) 2015-08-13 11:19:09 +00:00
90545b7046 Add config option for including remote deps in update
Remote deps are now moved out of update, because with the impending change of
plugin signer, all users will have all current JARs.
2015-08-13 11:00:06 +00:00
37b64f25c0 Fix hash verification 2015-08-12 12:10:49 +00:00
5f7bb2d7d1 Verify hashes of remote dependencies 2015-08-08 14:09:58 +00:00
69fc637bd7 Refactor remote dependency checking 2015-08-08 13:50:43 +00:00
cb0b0822a3 Upgrade to JavaMail 1.5.4, make it a remote dependency 2015-08-08 13:47:57 +00:00
f83f7cd085 Updated translations 2015-08-05 13:01:19 +00:00
bab92e082f Upgrade BouncyCastle to 1.52 2015-08-05 12:56:10 +00:00
d1e7eeb7bc Updated translation strings 2015-08-05 01:52:23 +00:00
a5409b0e43 Added new translations 2015-08-05 01:43:08 +00:00
742c697150 Updated translations 2015-08-05 01:42:37 +00:00
42c6269cda Improve recipient handling in email composition 2015-08-05 01:38:21 +00:00
03012e5323 Get IMAP STARTTLS working 2015-08-04 16:23:58 +00:00
97825a3d60 Upgrade to 20150627 snapshot of Apache James 2015-08-04 16:18:29 +00:00
dc5d066775 Get tests to pass 2015-08-03 13:21:57 +00:00
c2bc331b55 Add Email Date header tests 2015-08-03 13:19:17 +00:00
8f29c7d6fb Force loading of BouncyCastly so tests pass 2015-08-03 13:18:49 +00:00
6b530a364b Add direct link to creating tickets for I2P-Bote 2015-07-31 04:01:41 +00:00
3f60643c2e Updated history 2015-07-23 09:34:49 +00:00
3539b5a13b Don't move metadata file if we couldn't move email file (#1196) 2015-07-23 02:37:25 +00:00
e37f70506d Don't assume that email metadata file exists (#1196) 2015-07-23 02:27:09 +00:00
4196486799 Fix NPE (#937) 2015-07-22 21:16:18 +00:00
6dbecc0f6e Unused import 2015-07-22 12:30:51 +00:00
d209c9f94b Delete malformed packets from disk (#1287)
Incomplete email packets are unaffected because IncompleteEmailFolder overrides
the default behavior.
2015-07-22 11:44:49 +00:00
6e528dae6a Fix CME caused by no synchronization on kBuckets (#1586) 2015-07-21 10:09:32 +00:00
90f9de4861 Updated guide translations 2015-07-21 09:01:58 +00:00
f7b3499e93 Updated translations 2015-07-21 08:47:31 +00:00
5901565d74 Listen to identity updates too 2015-06-05 10:08:39 +00:00
f98990ad65 Added IdentitiesListener 2015-06-05 09:37:10 +00:00
d290665a17 New user guide translation for es 2015-03-20 09:31:16 +00:00
e2e2233b89 User guide fixes (thx strel!) 2015-03-20 09:25:31 +00:00
29190552d9 Updated translations 2015-03-20 09:24:29 +00:00
371ae89bc3 Preparation for moving StrongTls to i2p.jar:
- Removed last of pre-existing code
- Moved to net.i2p.util package
- Relicensed to public domain
- Improved interface
2015-03-19 19:49:55 +00:00
a34da62789 Overhauled StrongTls with 2015-era protocols and ciphers 2015-03-19 00:51:35 +00:00
8ff2c84cd4 Discovered that one of the old bootstrapping nodes is kytv, now resurrected 2015-03-16 10:12:19 +00:00
96140a49c5 New bootstrap peers (thanks str4d and The_Tin_Hat!) 2015-03-16 06:06:18 +00:00
b3f9ea8a0b Updated TODO 2015-03-12 21:45:10 +00:00
034660d4af Updated translations 2015-03-10 11:28:10 +00:00
bbda61316e Formatting changes by Transifex, and some string fixes 2015-03-10 11:22:45 +00:00
297a26cc63 Added user guide and FAQ to Transifex config 2015-03-10 11:22:26 +00:00
c9686adaef More formatting fixes for Transifex 2015-03-10 10:57:59 +00:00
82d31e4813 Formatting fixes for Transifex 2015-03-10 10:49:55 +00:00
63c17045b6 Multi-line Spanish translation 2015-03-10 10:40:06 +00:00
0566e42f21 New translation of FAQ into Spanish (thanks trolly!) 2015-03-10 04:16:22 +00:00
a21f67d429 Fixes 2015-02-15 10:52:36 +00:00
d7ae6d51e5 FAQ navigation 2015-02-15 10:23:13 +00:00
271eb004b2 Android themed wait.gif 2015-02-15 09:21:46 +00:00
c65e3f8f7e UI option for global identity check 2015-02-15 09:21:30 +00:00
dd7f4055a1 Prevent potential NPE 2015-02-15 09:20:52 +00:00
9b0836249d Bugfix 2015-02-15 07:13:17 +00:00
0585f211fb Implement checking individual identities 2015-02-15 03:25:40 +00:00
4df989d63a Don't disable default selection for new identities when only one exists 2015-02-14 22:33:59 +00:00
a76789cf30 Button layout fix 2015-02-14 22:33:34 +00:00
ae55336e06 Updated translations 2015-02-14 22:32:50 +00:00
437c5ddbac Backend implementation of per-identity relay settings, global check exclusion 2015-02-14 21:51:01 +00:00
63a574f578 Show which nav item is currently selected 2015-02-13 02:21:53 +00:00
42c3e0d369 Match nav drawer list item highlight to Material design spec 2015-02-13 02:01:13 +00:00
5d89032b90 Corrections from Material design spec 2015-02-13 01:55:57 +00:00
fc738142fa Moved getBooleanParameter() and getIntParameter() to Util 2015-02-07 19:51:39 +00:00
4e9b0e93cb Extract String constants 2015-02-06 10:00:05 +00:00
8912cfcf7d Include HTML files in WAR 2015-02-05 10:33:06 +00:00
73e22a3d34 Reference ticket numbers in TODO 2015-02-05 09:36:42 +00:00
dfa1dfbd74 Settings headings 2015-02-04 11:21:27 +00:00
eff95792ac Updated translations 2015-02-04 11:00:52 +00:00
bf53778367 String fix 2015-02-04 11:00:29 +00:00
74bde7aac6 HTML5 cleanups 2015-02-04 01:14:44 +00:00
848ec8cb14 Added not-yet-implemented features to TODO 2015-02-04 00:56:29 +00:00
a72bd3fb04 FAQ formatting 2015-02-03 14:22:22 +00:00
87ce7646f6 FAQ pagetitle 2015-02-03 14:19:29 +00:00
e2c003503a Reformatted FAQ 2015-02-03 14:16:46 +00:00
4f9d717725 List tweaks 2015-02-03 12:58:16 +00:00
f638d8e43a Limit user guide navigation width 2015-02-03 12:30:11 +00:00
2377acf15c Reorganized user guide sections 2015-02-03 12:29:19 +00:00
f11af022b2 User guide navigation 2015-02-03 12:25:31 +00:00
9ef5a15650 Removed unnecessary installation details, renumbered headings 2015-02-03 11:59:50 +00:00
02bb52dc67 Title fixes 2015-02-03 11:51:41 +00:00
bd9a0bd6b4 Consolidated credits 2015-02-03 11:32:04 +00:00
fe7516c24f Reworked user guide intro 2015-02-03 08:43:54 +00:00
97c567a105 User guide fixes 2015-02-03 04:55:16 +00:00
62308d053d Translation string fixes 2015-02-03 04:55:02 +00:00
f4ebc330a1 Translation fixes 2015-02-03 04:54:42 +00:00
93cabe4f44 Updated translation strings 2015-02-03 04:28:37 +00:00
5222861962 Proper theme names 2015-02-03 04:15:55 +00:00
9c09c739d2 Fixed bundle-messages.sh 2015-02-03 04:15:46 +00:00
8b3770f33d New translations 2015-02-03 03:52:46 +00:00
cd5d8b0ac2 Updated translations 2015-02-03 03:52:32 +00:00
596aa39d5d Updated Transifex config 2015-02-03 03:52:25 +00:00
212ca673b0 Updated TODO 2015-02-03 03:41:01 +00:00
9833590266 Move HTML files to subdir in preparation for Transifex 2015-02-03 03:40:50 +00:00
77242920bd Updated French translation of user guide 2015-02-03 03:33:22 +00:00
19a8c09a8d User guide tweaks 2015-02-03 03:33:00 +00:00
2634398ea4 Renamed user guide HTML 2015-02-02 22:41:19 +00:00
2fac3e9eae Tidied up user guide HTML 2015-02-02 22:40:04 +00:00
182bafb524 Enable HTML files to be themed 2015-02-02 22:32:52 +00:00
d7c673e4be Charts on network status page 2015-02-02 03:17:28 +00:00
33273675da Mark new relay peers instead of showing 0% reachability 2015-02-01 04:43:45 +00:00
7b405764fb NPE fix (ticket #1367) 2015-01-30 06:03:01 +00:00
750305fef1 Attachments icon 2015-01-30 05:38:57 +00:00
269f0d07e9 Improved info and error message displaying 2015-01-29 05:03:26 +00:00
7aae76ef4b Fixes after XSSFilter 2015-01-29 04:39:03 +00:00
302414a53d Enable different page title from browser title, more sidenav icons 2015-01-29 04:38:21 +00:00
22732d33c1 Missing bcprov changes 2015-01-28 23:54:55 +00:00
b113dd3e51 Font changes 2015-01-28 08:04:53 +00:00
ca0ac05614 Import identities 2015-01-28 06:47:47 +00:00
54ac8425b5 Export identities 2015-01-28 04:33:03 +00:00
67e36d834e Escape XML 2015-01-28 04:25:51 +00:00
48c2294517 HTML5 <time> 2015-01-27 02:48:12 +00:00
e3e694d0c9 Enable XSSFilter on all inputs except passwords 2015-01-27 01:43:12 +00:00
06fc60af43 Material tweak for new emails 2015-01-27 01:41:33 +00:00
9cd8bddf8a Bugfix 2015-01-27 01:30:29 +00:00
6c4ab4b1b3 NPE fix when attempting to change identity name to blank 2015-01-27 01:14:33 +00:00
3155308054 New theme based on the Material design of the Bote Android app 2015-01-26 10:32:42 +00:00
538a5b2e06 Change addressbook.gif to addressbook.png 2015-01-26 10:02:05 +00:00
dd126df6c7 Inputs to buttons 2015-01-26 07:41:43 +00:00
a1edb3173c Remove onclick from header, the inbox is easily accessed from the side nav 2015-01-26 04:56:34 +00:00
edc51acedb An article around email content 2015-01-26 04:24:07 +00:00
0394b591a7 Extra page title for use in new theme 2015-01-26 03:45:03 +00:00
9a5a161342 CSS tweak 2015-01-25 10:19:05 +00:00
ec3acae530 Replaced linebreak with margin 2015-01-25 09:32:05 +00:00
7fea66978b Remove "Public Address Directory" from side nav until it has a link 2015-01-25 09:21:16 +00:00
b7abb03b32 HTML5, preparations for new theme 2015-01-25 09:18:40 +00:00
958a072d9b HTML5 doctype and charset 2015-01-24 12:31:42 +00:00
e7042dc5a7 Detect file MIME types 2015-01-12 07:55:51 +00:00
bc6df473be Ask for plugin SU3 keystore password 2015-01-12 07:34:17 +00:00
04ac90d478 Prevent NPE on Android if the state gets weird (it has happened) 2015-01-11 12:25:45 +00:00
7e8421c63b Added ignores 2015-01-11 05:51:22 +00:00
3591d25f72 Migrate i2p.bote.crypto AES and EC to JCA; upgrade to BouncyCastle 1.51
This change was necessary to fix the crypto on Android, where SpongyCastly must
be used instead (because of classloader conflicts). The new ECUtils class
contains the remaining code that could not be made provider-agnostic. In
particular, the EmailDestination format for EC requires the use of BouncyCastle
point encoding.

The full BouncyCastle library is now bundled, because it must be added as a
Security Provider to use the JCA system, and this requires a valid signature.

JCA is used for AES operations instead of I2P's built-in AES engine because the
PKCS#7 padding class could not be accessed on its own in a provider-agnostic
manner. The resulting code is also cleaner.
2015-01-04 22:16:16 +00:00
1f1b328f70 Close InputStream in Util.getPartSize() 2015-01-04 05:00:08 +00:00
823491ae4d Pull out Util method for getting size of a Part 2014-12-28 11:42:23 +00:00
6856773636 Correct the Attachment interface 2014-12-28 11:42:02 +00:00
2cc3df7c1f Generalize attachments 2014-12-28 04:52:27 +00:00
852bad8d61 Moved JSPs to correct location
For i2pbote.war the location doesn't matter, because the JSPs are compiled. For
the Eclipse testnet, the JSPs are not compiled and cannot be located because
access to files in WEB-INF is restricted.
2014-12-23 10:47:11 +00:00
4f357db8ec Use I2PSocketManagerFactory.createDisconnectedManager() for better connectError 2014-12-17 23:54:31 +00:00
877b02cc04 Layout fix 2014-12-13 10:56:30 +00:00
8b5b7507c6 Helpers to get the name for an EmailDestination 2014-11-18 04:00:00 +00:00
5ff770bc31 Use assertArrayEquals 2014-11-17 22:39:04 +00:00
4107467c64 Mockery thread synchronization 2014-11-17 22:23:20 +00:00
05def741fb Fix BCC header removal bug 2014-11-17 21:41:57 +00:00
82ac0d59d8 Unused imports 2014-11-17 21:25:00 +00:00
10445e1082 junit.framework -> org.junit 2014-11-17 21:15:00 +00:00
a968f5c6f4 Updated history 2014-09-25 05:54:49 +00:00
d6564680a5 Update to techdoc by HungryHobo 2014-09-25 05:54:31 +00:00
ec41d7d82e Switch to Maven directory structure without losing history 2014-09-25 05:50:39 +00:00
8a29b9dd0d Mark locations of code incompatible with newer I2P Destinations 2014-09-21 05:32:43 +00:00
6c53344f51 A zero-length password is an uncached password
This brings PasswordCache in line with FileEncryptionUtil.
2014-09-21 05:31:08 +00:00
2768297be9 Add and remove interface for password listeners 2014-09-18 06:11:01 +00:00
740197e439 Added TODO 2014-08-26 11:55:12 +00:00
6e4c52b746 Remove spaces and newlines 2014-08-07 11:56:43 +00:00
cc59ed9adb Remove possible prefixes 2014-08-07 11:46:58 +00:00
3c0a431f09 Remove UpdateChecker
Plugins have been auto-updated by the router for a while now
2014-08-03 10:47:11 +00:00
392ba71037 Another Tomcat 7 fix, see rev. 5e9c9148 2014-08-03 10:42:32 +00:00
e39abcc145 Use SecureFile instead of Util.makePrivate()
* Replace Util.makePrivate() with SecureFile and SecureFileOutputStream
* Make derivparams a SecureFile
2014-08-02 16:46:17 +00:00
e030e9ed5f 0.2.10 2014-07-23 21:36:12 +00:00
1896fccf1f Fix NullPointerExceptions 2014-07-23 21:25:31 +00:00
ca19e9d9e0 Use a separate SessionKeyManager instead of the router's 2014-07-23 21:24:39 +00:00
729a4ac99f Upgrade to 20140722 snapshot of Apache James 2014-07-23 21:22:15 +00:00
729f59e729 Support I2CP connections over Unix domain sockets
Only supported on Android for now.
2014-07-16 04:05:35 +00:00
78b66b5509 Bugfix after net.i2p.data.Base64.decode() errors were cleaned up 2014-07-07 00:28:22 +00:00
5cdcae1416 Missing network status change 2014-07-06 14:26:47 +00:00
348262e7a2 NetworkStatusListener implementation 2014-07-06 13:05:39 +00:00
adb290658a Inform caller if importer found no identities 2014-07-06 02:55:44 +00:00
c04fc24445 Implement encrypted identities export 2014-07-06 02:28:40 +00:00
4762f8486e Implement identity appending on import 2014-07-05 23:50:02 +00:00
52a717d7e3 Import identities from FileDescriptor (no appending possible yet) 2014-07-05 04:23:19 +00:00
e9ffb4643b Export identities to file (no encryption possible yet) 2014-07-04 06:21:17 +00:00
382f75f4a4 Pulled out Identities <-> Properties conversion into separate methods 2014-07-04 00:23:14 +00:00
4a6fc262e7 Show number of incomplete emails 2014-07-02 09:23:58 +00:00
4cd24cd579 Expose number of incomplete emails 2014-07-02 06:38:02 +00:00
32ce92d7cb Updated license.txt 2014-06-23 01:47:07 +00:00
96bb3a0719 Enable saving picture for EmailIdentity 2014-06-16 05:41:11 +00:00
5cebc0b2ee Added EmailIdentity.setPictureBase64() 2014-06-16 04:57:32 +00:00
4e7d57d8e3 Implement vanity destinations 2014-06-11 21:11:11 +00:00
0ad03ce6d4 Fix for new Jetty/Tomcat 2014-06-11 06:13:13 +00:00
2082fd0856 Emails are not kept in-memory inside EmailFolder, so store \Recent in metadata 2014-06-10 12:17:35 +00:00
98c56de3a5 Added specific listener for newly-received emails 2014-06-09 04:51:20 +00:00
1801e308b2 Fixed bug in setFlags() 2014-06-08 06:46:56 +00:00
f318587209 Helper method 2014-06-08 04:59:13 +00:00
38d5833551 Improved FolderListener, emails added to a folder outside IMAP now get \Recent 2014-06-08 04:12:30 +00:00
6bbd015d38 Store other IMAP flags in-memory (like \Recent) 2014-06-08 02:59:39 +00:00
f20ae940a8 Add missing file 2014-06-03 06:01:55 +00:00
f7f185a68c Handle index packets that are bigger than a datagram (fixes "After merging, IndexPacket is too big..." errors) 2014-06-02 21:01:26 +00:00
a47100d14a Fix NullPointerException on fresh installs 2014-05-29 22:21:09 +00:00
32bd6e45a8 Fixes for Tomcat 7 which is more anal about the JSP spec than Jetty or Tomcat 6 2014-05-29 22:14:28 +00:00
ca19b0929e NPE fix for corrupt folder 2014-05-24 00:00:34 +00:00
3dede23a24 Reworked email status storage for UI flexibility 2014-05-23 01:18:18 +00:00
e190587330 Reverted bad log tweak 2014-05-17 04:37:23 +00:00
0d92ddb6e1 Set connectTask to null so getNetworkStatus() returns valid state 2014-05-17 04:36:42 +00:00
52f6405c74 Removed unused import 2014-05-17 04:33:28 +00:00
99fb8bf264 NPE fixes, log tweak 2014-05-17 04:27:59 +00:00
fa22d47252 Whitespace, don't create SSL key store on Android 2014-05-17 04:21:06 +00:00
2dfa656b06 JSSE requires keystore and key passwords to be identical 2014-05-13 05:07:05 +00:00
56aa3f3c1c Generate the SSL cert on-the-fly to prevent MITM 2014-05-13 02:23:09 +00:00
c2e75290fb Reverted mistaken checkin 2014-05-13 02:20:19 +00:00
3387cdd90c Enable STARTTLS for IMAP and SMTP using selfsigned certificate
Certificate domain is 127.0.0.1, clients will throw a warning if using localhost
(alongside the warning for selfsigned cert).
2014-05-12 13:49:13 +00:00
c3088c5931 Mark important comments 2014-05-12 13:23:28 +00:00
a149a0bdc0 Fixed NPE (ticket #1272) 2014-05-12 12:37:47 +00:00
7867198fe9 Override updateMessageID() on Android to prevent NetworkOnMainThreadException 2014-04-17 23:27:40 +00:00
38293ebcf9 Added elementUpdated() to FolderListener, made setNew() throws consistent 2014-04-16 13:07:17 +00:00
6f4a0615ff Update FolderListeners when Email is moved 2014-04-15 00:58:02 +00:00
22fa6105ac Updated FAQ and User's Guide 2014-04-14 02:30:00 +00:00
946fa8d6ec Insert addressbook/identity names, @bote, {UNK} into IMAP email headers 2014-04-14 02:29:37 +00:00
5a8d9c6f4f Remove @bote before validating sender and recipient addresses in SMTP 2014-04-13 05:05:41 +00:00
5c53c2071b Updated about.jsp 2014-04-13 02:45:57 +00:00
c84770036d Create BoteMailboxes once, and remove their FolderListeners when IMAP stops 2014-04-13 02:27:31 +00:00
d9756407b0 Refactor to handle recipient headers containing multiple recipients 2014-04-13 01:46:13 +00:00
fe9c6d9d47 Pack new mailapi.jar in update for 0.2.10 2014-04-11 22:42:07 +00:00
ee96addef6 Removed signature from scrypt jar (pack200 interferes) 2014-04-10 21:51:49 +00:00
1f9aa61d2f Upgraded to scrypt 1.4.0 2014-04-10 20:59:44 +00:00
zzz
5e559846db one more typo 2014-04-07 13:26:10 +00:00
bbd24eaaff fix another missing '/' 2014-04-07 12:20:12 +00:00
4db680f067 add missing / to paths 2014-04-07 12:14:44 +00:00
79595913f2 Previous fix wasn't quite right 2014-04-04 20:01:29 +00:00
b387b77bfb Fixed concurrency problem 2014-03-30 03:10:04 +00:00
dce43d11ae Fixed IMAP UID implementation to conform to RFC 3501 2014-03-30 02:14:56 +00:00
8fec6b28e8 Remove @bote properly from SMTP messages 2014-03-29 03:19:53 +00:00
17282cda4d Missing Bean method 2014-03-28 20:58:26 +00:00
1664253417 Fixed password "corruption" (ticket #1239) 2014-03-28 20:57:56 +00:00
654b136cb0 Somehow, file duplication has stopped 2014-03-18 20:04:50 +00:00
2b5de7958e Doc tweak 2014-03-18 10:56:28 +00:00
10b9b2e593 Updated identity file spec 2014-03-18 10:22:47 +00:00
3571adf2ec Another StatusListener 2014-03-09 23:05:22 +00:00
44027e80ca Save and load default key properly 2014-03-09 09:11:00 +00:00
9d821f66b9 Update default identity when changed (for writing to file) 2014-03-08 23:07:54 +00:00
bef847d270 Moved Servlet-dependent helper methods back to JSPHelper 2014-03-04 01:46:56 +00:00
967a523130 Missing javadoc @param 2014-03-04 01:36:11 +00:00
c35e9c9139 Enable listening to status of internal operations (for Android UI) 2014-03-02 10:32:23 +00:00
c0b62e25c1 Remove throw (handled in rev 78f6a5bcf158019aceb75a48aebd8d9c20b203ce) 2014-03-01 01:55:15 +00:00
936e1e7d50 Updated techdoc.txt for mailapi.jar 2014-02-28 22:08:34 +00:00
592793eaac Add a setting to enable/disable SMTP 2014-02-28 22:02:49 +00:00
f1c9ac9788 Updated to mailapi 1.5.1 2014-02-27 05:19:54 +00:00
bdd24d7e9d Apparently Jasper can't follow inheritance 2014-02-27 04:40:15 +00:00
de36d91909 Delete i2pbote.jar in clean 2014-02-27 03:28:18 +00:00
1a6ae22b99 Allow using result of folder.getName() in getMailFolder()
This is used for saving instance state in Android.
2014-02-27 03:00:03 +00:00
adde9736be Split JSPHelper so common utilities can be used by other UIs (Android) 2014-02-26 23:08:34 +00:00
173d08d798 Allow FolderListeners to be removed 2014-02-26 07:07:42 +00:00
acb1ace33a Don't add source files to i2pbote.jar (it duplicates .txt files) 2014-02-26 07:07:11 +00:00
ffa7450e77 Reordered list of folders 2014-02-26 03:28:18 +00:00
d9d9c47124 Add README.md for GitHub 2014-02-16 18:18:45 +00:00
d960308461 Update techdoc.txt 2014-02-16 13:41:27 +00:00
616df8de9f Update translations from Transifex 2014-02-16 13:40:34 +00:00
427e293bac 0.2.9 2014-02-16 13:39:32 +00:00
163f8d58c0 Make send button easier to find 2014-01-08 01:44:02 +00:00
43e34eb221 Added code to mapper for fetching recent messages
This functionally changes nothing, because BoteMessage.isRecent()
always returns false.
2014-01-01 21:30:02 +00:00
c2d1334c04 Unset flags correctly 2014-01-01 05:57:41 +00:00
a05890eaec Implemented deleting via IMAP
The \Deleted flag is stored in EmailMetadata, but is ignored by Bote and only
used for IMAP deletion.
2013-12-31 20:20:17 +00:00
2a744fb1cd RFC 2822: set From: header 2013-12-31 16:43:55 +00:00
ed60728edd Don't delete libs with "ant clean" 2013-12-31 07:29:26 +00:00
48e69d3cd5 Don't break folder list if an email can't be decrypted 2013-12-27 02:33:26 +00:00
df09332ead Added libs to .jar manifest (so IMAP setting works) 2013-12-26 09:54:01 +00:00
585413fa2b Fixed potential NPE 2013-12-25 23:30:02 +00:00
68c48cb332 Update to jMock 2.6.0 (v2.5.1 is not available from their website anymore) 2013-05-01 18:12:55 +00:00
ae87a801ea Fix classpath and typos 2013-05-01 17:52:44 +00:00
901b051546 Implement SMTP 2013-05-01 17:50:42 +00:00
6590e3122a Shorten known email destinations in the folder view 2013-04-29 19:18:02 +00:00
e601b5f46e Add a setting to enable/disable IMAP 2013-04-29 18:53:41 +00:00
641085ab24 don't try to zip up non-existent images directory (see rev. 1ae37d314f064cfb6c870727775f5b5ccc5ea69e) 2013-04-29 18:34:15 +00:00
5d371f983a IMAP interface, works with Thunderbird but not Evolution 2013-04-29 00:21:37 +00:00
8fc111fc86 Fix Content-Transfer-Encoding (8bit doesn't allow zeros, CR, or LF) 2013-04-26 23:15:13 +00:00
2dc809c025 Close streams when done reading 2013-04-26 23:06:15 +00:00
7b0149dc39 by request, adding my i2pbote node's public destination 2013-04-11 16:00:55 +00:00
24509df2b5 Delete commented out line 2013-04-02 21:47:28 +00:00
263b68550e Fix a compiler warning 2013-04-02 21:42:34 +00:00
ae3ac8b5be Attach file on selection when JS is enabled 2013-04-02 21:33:36 +00:00
7c22899f32 try supressing/fixing a few warnings 2013-04-01 21:01:18 +00:00
3970d6d015 build fix (don't try to zip up non-existent images directory) 2013-04-01 20:40:12 +00:00
4464301119 Remove unused images 2013-04-01 18:08:37 +00:00
f0622d202b Move style attributes to CSS 2013-04-01 17:57:59 +00:00
63e260f932 Show anonymous sender in italics 2013-03-31 22:36:24 +00:00
87ad8db92a Display of signatures:
* Combine signature column and replied column
 * Don't show signature warning for anonymous emails
2013-03-31 22:23:00 +00:00
cc7e0209ec Simplification 2013-03-30 23:01:32 +00:00
1a4c25a32f Add a null check 2013-03-30 22:58:14 +00:00
79339a0208 Fix a comment 2013-03-30 22:57:26 +00:00
249389a4d3 Replace ReentrantLock with synchronized 2013-03-30 08:55:16 +00:00
92a5a998d6 Show a wait page when the password is changed 2013-03-29 17:09:10 +00:00
e1a49cf440 Add a JSP that allows users to check encrypted files 2013-03-24 12:32:31 +00:00
458 changed files with 41397 additions and 17693 deletions

69
.mtn-ignore Normal file
View File

@ -0,0 +1,69 @@
# Just to try and prevent some noob disasters.
# Use mtn add --no-respect-ignore foo.jar to ignore this ignore list
# Temporary/build files
i2pbote.jar
i2pbote.xpi2p
i2pbote-update.xpi2p
~$
# Temporary/build dirs
^ant_build
^plugin/plugin.tmp
# Build property overrides
override.properties
# Downloaded JavaMail libraries
mailapi-.*.jar
# Downloaded BouncyCastle Provider libraries
bcprov-jdk15on-.*.jar
# Downloaded IMAP libraries
apache-james-imap-api-0.4-.*.jar
apache-james-imap-message-0.4-.*.jar
apache-james-imap-processor-0.4-.*.jar
apache-james-mailbox-api-0.6-.*.jar
apache-james-mailbox-store-0.6-.*.jar
apache-mime4j-core-.*.jar
apache-mime4j-dom-.*.jar
commons-codec-.*.jar
commons-collections-.*.jar
commons-configuration-.*.jar
commons-io-.*.jar
commons-lang-.*.jar
james-server-filesystem-api-3.0.0-beta5-SNAPSHOT.jar
james-server-lifecycle-api-3.0.0-beta5-SNAPSHOT.jar
james-server-protocols-imap4-3.0.0-beta5-SNAPSHOT.jar
james-server-protocols-library-3.0.0-beta5-SNAPSHOT.jar
james-server-util-3.0.0-beta5-SNAPSHOT.jar
jutf7-1.0.0.jar
log4j-1.2.17.jar
netty-3.3.1.Final.jar
protocols-api-1.6.4-.*.jar
protocols-imap-1.6.4-.*.jar
protocols-netty-1.6.4-.*.jar
slf4j-api-.*.jar
slf4j-log4j12-.*.jar
# Downloaded SMTP libraries
subethasmtp-3.1.7.jar
# Downloaded JUnit libraries
junit-4.8.1.jar
# Downloaded Mockito libraries
mockito-core-2.0.31-beta.jar
# Downloaded jMock libraries
cglib-nodep-2.2.3.jar
hamcrest-core-1.3.jar
hamcrest-library-1.3.jar
hamcrest-unit-test-1.3.jar
jmock-2.6.0.jar
jmock-junit3-2.6.0.jar
jmock-junit4-2.6.0.jar
jmock-legacy-2.6.0.jar
jmock-script-2.6.0.jar
objenesis-1.0.jar

View File

@ -1,22 +1,21 @@
[main]
host = https://www.transifex.com
lang_map = ru_RU: ru, sv_SE: sv, tr_TR: tr, uk_UA: uk, zh_CN: zh
[I2P.plugin_i2pbote]
file_filter = locale/messages_<lang>.po
source_file = locale/messages_en.po
source_lang = en
trans.ar = locale/messages_ar.po
trans.cs = locale/messages_cs.po
trans.de = locale/messages_de.po
trans.es = locale/messages_es.po
trans.fr = locale/messages_fr.po
trans.hu = locale/messages_hu.po
trans.it = locale/messages_it.po
trans.nl = locale/messages_nl.po
trans.nb = locale/messages_nb.po
trans.pl = locale/messages_pl.po
trans.pt = locale/messages_pt.po
trans.ru = locale/messages_ru.po
trans.sv_SE = locale/messages_sv.po
trans.uk_UA = locale/messages_uk.po
trans.vi = locale/messages_vi.po
trans.zh_CN = locale/messages_zh.po
minimum_perc = 40
[main]
host = http://www.transifex.net
[I2P.plugin_i2pbote_userguide]
file_filter = src/main/webapp/html/userGuide_<lang>.html
source_file = src/main/webapp/html/userGuide.html
source_lang = en
minimum_perc = 50
[I2P.plugin_i2pbote_faq]
file_filter = src/main/webapp/html/FAQ_<lang>.html
source_file = src/main/webapp/html/FAQ.html
source_lang = en
minimum_perc = 50

28
README.md Normal file
View File

@ -0,0 +1,28 @@
# I2P-Bote
I2P-Bote is a plugin for I2P that allows users to send and receive emails while preserving privacy. It does not need a mail server because emails are stored in a distributed hash table. They are automatically encrypted and digitally signed, which ensures no one but the intended recipient can read the email, and third parties cannot forge them.
**Features:**
* Themeable webmail interface
* User interface translated in many languages
* One-click creation of email accounts (called email identities)
* Emails can be sent under a sender identity, or anonymously
* ElGamal, Elliptic Curve, and NTRU Encryption
* Encryption and signing is transparent, without the need to know about PGP
* Delivery confirmation
* Basic support for short recipient names
* IMAP / SMTP
**Planned Features:**
* Custom folders
* Sending and receiving via relays, similar to Mixmaster
* Lots of small improvements
**More information**
The links below only work within I2P, i.e., make sure you are running I2P and your browser is using the proxy at localhost:4444.
* http://i2pbote.i2p I2P-Bote homepage
* http://forum.i2p/viewforum.php?f=35 I2P-Bote forum

28
TODO Normal file
View File

@ -0,0 +1,28 @@
User guide
- Howto for IMAP/SMTP
Email composition
- "Include sent time" as an option, pre-filled with settings default
Identities
- Generate dests in background rather than needing a dedicated tab open
IMAP/SMTP
- "Force SSL" option
- When disabled, users can connect with "insecure" or "STARTTLS"
- When enabled, users can connect with "SSL"
- Separate password cache (IMAP auth should not unlock webui)
Not-yet-implemented
- Drafts folder
- User-defined folders
- Automatically disable timestamps when using mail routes
- Random offset for fetch interval (#1360)
- Per-identity settings (#1359)
- Fetch interval
- Mail route per-hop settings
- Delay (#1361)
- Fixed forward time
- Traffic correlation countermeasures at relays
- Mixing anonymity (minimum threshold on relay packets to send)
- Constant traffic (test and dummy messages)
- Balanced incoming/outgoing ratio
- Packet padding
- Retrieving email via relays

View File

@ -1,462 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Frequently Asked Questions</title>
<meta http-equiv="Content-Language" content="English" />
<meta name="Robots" content="index,follow" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" type="text/css" href="css/style.css" media="screen" />
</head>
<body>
<div id="wrap">
<div id="top">
<div class="rights"> </div>
<div id="search">
</div>
<div class="lefts">
<h1>I2P-Bote</h1>
<h2>Secure Distributed Email</h2>
</div>
</div>
<div id="topmenu">
<div class="rights"></div>
<div class="lefts"><ul>
<li><a href="index.html" title="Home">HOME</a></li>
<li><a href="download.html" title="Download I2P-Bote">DOWNLOAD</a></li>
<li><a href="screenshots.html" title="Screenshots">SCREENSHOTS</a></li>
<li><a href="userguide.html" title="User Guide">USER GUIDE</a></li>
<li><a href="faq.html" title="Frequently Asked Questions">FAQ</a></li>
<li><a href="http://forum.i2p/viewforum.php?f=35" title="Forum">FORUM</a></li>
<li><a href="contact.html" title="Contact">CONTACT</a></li>
</ul></div>
</div>
<div style="text-align: justify;" id="main">
<div id="leftside">
<p>
<h2>Frequently Asked Questions</h2>
</p>
<p>
<div class="date"></div>
</p><p>
<strong>What is I2P-Bote?</strong><br/>
A peer-to-peer email program designed to protect your privacy.<br/>
I2P-Bote is an end-to-end encrypted, network-internal, fully decentralized
(serverless) e-mail system. It supports different identities and does
not expose e-mail headers. Currently, it is still alpha software and
can only by accessed via web console. It soon will have POP3 support,
and it is planned to guarantee additional anonymity by providing a
high-latency transport option. All bote-mails are automatically
end-to-end encrypted, so that there's no need to set up e-mail
encryption (though the option does exist), and bote-mails will be
authenticated automatically. As
it is decentralized, there is no e-mail server that could link
different e-mail identities as communicating with each other
(profiling): Even the nodes relaying the mails will not know the
sender and apart from sender and receiver, only the end of the
high-latency mail tunnel and the storing nodes will know to whom
(anonymous identity) the mail is destined. The original sender can
have gone offline, long before the mail becomes available on the
other side. This adds on the degree of anonymity that can be reached
with I2P-Bote. For those who do not want high delays: All these
settings are be user-adjustable, so each user decides on how much
anonymity he wants.
</p>
<div class="date"></div>
<p>
<strong>Why is it named I2P-Bote?</strong><br/>
Bote is the German word for messenger.
</p>
<div class="date"></div>
<p>
<strong>Why I2P-Bote?</strong><br/>
Because it's cool.
And because I2P was lacking a decentralized e-mail service, and seeing
the creation of such as an opportunity to improve on neglected
anonymity aspects, it was decided to add an optional high-latency
transport. You can use a normal e-mail account and end-to-end encrypt your mails, but
they are still not anonymous. You can use anonymous server-bound e-mails, yet they are not automatically
end-to-end encrypted.<br>
Or you can use I2P-Bote in which your mails
are anonymous and <i>automatically</i> end-to-end-encrypted.<br>In contrast
to standard e-mail systems there is no need to setup an additional
key management application. Everything you need is already there. <br/>But
despite it being simple and easy to use, it still offers military
grade encryption and options for extremely strong anonymity.
</p>
<div class="date"></div>
<p>
<strong>What happens with an email after I click "Send"?</strong><br/>
It is encrypted and stored on other I2P-Bote participants' computers. From there, it is delivered to the recipient when they check their email.
</p>
<div class="date"></div>
<p>
<strong>Wait a minute, all email I send is saved on some random person's hard drive? That sounds like a really dumb idea!</strong><br/>
All they see is garbage data because it is encrypted with "military-grade" encryption. Only you and the recipient know what is in the email. Additionally, if you send the email with relays enabled, it is not even possible to tell who sent it.<br/>
Between this and using an email account with a
<a href="http://www.theregister.co.uk/2009/12/07/schmidt_on_privacy/">company that doesn't respect your privacy</a>, over an internet line that <a href="http://www.eff.org/issues/nsa-spying">is being spied on by shady agencies</a>, which would you say is more trustworthy?
</p>
<div class="date"></div>
<p>
<strong>How does it work exactly?</strong><br/>
&#8211; see the section &#8220;Concept&#8221; of the Manual &#8211;<br/>In short:
I2P-Bote nodes form a p2p-network, relaying mail packets for one another and storing them into a DHT.
</p>
<div class="date"></div>
<p>
<strong>Why would I use it? I have nothing to hide &hellip;</strong><br/>
Because you wouldn't go out to the street naked either, would you?<br/>Well, maybe you would. But the point is, sometimes you want private e-mail communication to be secret and untraceable and not let the whole world know when you say what to whom.<br/>
And sometimes you simply want to communicate fully anonymously with others.<br/>Therefor I2P-Bote is the ideal tool, giving you a hell lot of protection while preserving a great deal of flexibility.<br/>
It aims at providing professional military grade security and n00b-proof usability:<br/>
You can have really paranoid settings, where it takes a mail an eternity to arrive; or have faster communication and still enjoy very high anonymity.<br/>
You decide &#8211; easily with a click of your mouse.</p>
<div class="date"></div>
<p>
<strong>What about <a href="http://www.pgp.com/">PGP</a> and <a href="http://gnupg.org/">GPG</a>?</strong><br/>
PGP and GPG let you encrypt email and send it through your existing email account. They offer strong encryption, but they only encrypt the email text, not the headers, which means the subject line, your computer name, and other information is not secure.<br/>
Another privacy issue is that PGP/GPG cannot prevent anybody from finding out who is talking to whom.<br/>
I2P-Bote, in contrast, encrypts everything but the recipient's Email Destination. (In fact even the recipient's destination is only visible to nodes who do not know who the sender of the mail was.) It also has the ability to send an email through several relays (similar to <a href="http://mixmaster.sourceforge.net/">Mixmaster</a>), so nobody can find out who is sending email to whom.
<br/>
</p>
<div class="date"></div>
<p>
<strong>Can I still use GPG/PGP with I2P-Bote?</strong><br/>
Of course. Either have GPG encrypt your e-mail's text before pasting it into the I2P-Bote mail composition field, or use a mail app with GPG support. [<font color="#ff0000">POP3 support not implemented</font>]
</p>
<div class="date"></div>
<p>
<strong>How does it compare to Susimail?</strong><br/>
I2P-Bote is better because it has a higher version number. Just kidding.<br/>
I2P-Bote offers more privacy, but Susimail has some features I2P-Bote doesn't have yet (see below), and Susimail is more bandwidth-efficient because it doesn't store emails redundantly.
</p>
<div class="date"></div>
<p>
<strong>Why is I2P-Bote better?</strong><br/>
<i>We</i> think it's better for <i>us</i> (and maybe for you, too; decide yourself!), than &#8230; <ul><li><p style="line-height: 150%;"><font face="Arial, sans-serif">mixminion as it is easy to use and as n00b-proof as we could get it.</font></p>
</li><li><p style="line-height: 150%;"><font face="Arial, sans-serif">anonymous e-mail services not based on destination key routing: as those do not deliver built-in end-to-end encryption.</font></p>
</li><li><p style="line-height: 150%;"><font face="Arial, sans-serif">centralized services, as the server could go down (due to attacks, legal problems, lack of funding or interest, &#8230;) and the server admin has too many means to do profiling.</font></p>
</li></ul></p>
<div class="date"></div>
<p>
<strong>How is my identity kept safe when I exchange mail with someone?</strong><br/>
Never is your ip number or even your I2P-destination included in any e-mail you send.<br/>
The high-latency transport counters timing attacks.<br/>
End-to-end encryption, per-hop encryption, relaying packets for other nodes, one single packet size* (padding), a constant rate of sending (test and dummy messages)*, and a rather balanced incoming/outgoing ratio* counter traffic analysis attacks, and in combination with per-hop delays, I2P-Bote offers good means against intersection attacks.<br/>
The open source nature of I2P-Bote guarantees that you yourself can see the implementation and check it for bugs.
<br/>*[<font color="#ff0000">not yet implemented</font>]</p>
<div class="date"></div>
<p>
<strong>How do I use it?</strong><br/>
Read the manual or see the other questions and answers here!<br>
If you still have unanswered questions, ask on the forum:
<a href="http://forum.i2p/viewforum.php?f=35">http://forum.i2p/viewforum.php?f=35</a>
</p>
<div class="date"></div>
<p>
<strong>Can I use an email program like Thunderbird?</strong><br/>
No, but it is on the roadmap.
<!--Yes, you can use the e-mail client of your choice, as long as it supports POP3 and SMTP<br/>[<font color="#ff0000">POP3 and SMTP not yet implemented</font>]-->
</p>
<div class="date"></div>
<p>
<strong>Can I send attachments, and what limits are there?</strong><br/>
Yes, attachments are supported as of release 0.2.5.<br/>The overall size of attached files should be kept small, preferably below 500kB.</p>
<div class="date"></div>
<p>
<strong>How do I create an email account?</strong><br/>
I2P-Bote calls them Email Identities. You can create one in the I2P-Bote web interface under the "Identities" link. The reason why it's not called an account is that there is no provider like GMail or GMX. You alone hold the (cryptographic) keys to the Email Identity.<br/>
When you create an Email Identity, I2P-Bote generates a string of numbers and letters called an Email Destination. This is the address you can be reached at.<br/>
Example: <tt><b>wsq-8u5bTWbaOsrS0JuXRKL-RsbTkckV4W7u2mIu0Yrlfetixq1F~03CArnvbd6tDWwjPHYEuoKyWqwxplSdix</b></tt>
</p>
<div class="date"></div>
<p>
<strong>What's an Email Destination? What about email addresses?</strong><br/>
Email destinations (aka bote dests) are between 86 and 512 characters long, depending on the type of encryption. Support for easy-to-remember, user-chosen addresses is planned for the near future.<br/>
The e-mail identities consist of public and private keys, as well as a name the user chooses for it. The public part is your e-mail destination, your pseudonymous identity. And one real user can have more than one of those identities. They serve for addressing mails to certain users &#8211;therefore it is referred to as a &#8220;destination&#8221 or short &#8220;dest&#8221; &#8211; as well as for encrypting the mails for them.
Hence, your e-mail destination is the key others use in order to encrypt mails which they send to you, and in
order to verify the authenticity and integrity of mails they receive from you.<br/>
It is save to give your e-mail destination to anybody you want to get e-mails from.<br/>
It is important to distinguish between the mail dest and the router id! Your I2P-Bote mail identity is not related to your I2P-Bote router/node id, which is used for I2P-Bote nodes to contact each other and this way for the Bote network.<br>
If you have problems with your I2P-Bote app &#8211; in the highly unlikely case it should be necessary &#8211; you can tell your I2P-Bote router id in irc2p, I2P's IRC channels, or the forum or manually add other peer's id's in order to connect, though until now this has never been necessary. <br>It is <b>not linked to your ip</b>. Nonetheless, do not relate your I2P-Bote router id with your I2P-Bote mail dests since this might destroy the additional anonymity I2P-Bote itself generates!
</p>
<div class="date"></div>
<p>
<strong>Why are the e-mail addresses so long?</strong><br/>
In I2P-Bote every mail is (automatically) encrypted. In order not to require you to exchange an e-mail address <b>and</b> a long key, we simply made that key the address. This comes with two additional benefits: You won't have
to worry if an e-mail address is already taken or not (at least not if you do not send or receive e-mails to or from the internet) and you don't need a key management app apart, for taking care of your keys.<br>
It is safe to give away this key, as it is only the public key which everybody may know about without compromising your e-mails' secrecy.<br/>
Using the ECC encryption as option will yield shorter e-mail destination keys.
</p>
<div class="date"></div>
<p>
<strong>But I cannot remember those long destinations &#8230;</strong><br/>
That's what the integrated addressbook is there. Once you have become more acquainted qith I2P-Bote, you will appreciate the built-in encrpytion and authentication, which can only be achieved using cryptographic keys.
<br/>Again, the alternatove would be to have short and easy addresses <b>plus</b> a long key for encryption and authentication, <b>and</b> to rely on some authority to map the e-mail addresses to some anonymous recipient.
</p>
<div class="date"></div>
<p>
<strong>What's the point of using multiple mail identities?</strong><br/>
I2P-Bote is not an instant messenger, so you can have several identities without having to keep many tunnels open. Only for fetching requests you'd use up more resources but at the same time provide more cover for others.<br/>
Now, imagine you communicate with your friends unobservedly (see: data retention laws) via I2P-Bote, and want to quickly send out a mail that you'll be meeting each other in a different location tonight.
Then, you need no super-anonymity and can renounce mail routes and delays. Your friends, on the other hand, would want to have a shorter check interval, so they will receive the mail in time. Yet you still want super high anonymity for some of your other communications &#8231; that's where a different mail identity with mail routes, delays and long check intervals comes in handy.
</p>
<div class="date"></div>
<p>
<strong>Which encryption type is best?</strong><br/>
256-bit <a href="http://en.wikipedia.org/wiki/Elliptic_curve_cryptography">ECC</a> produces short and handy Email Destinations, and it is considered stronger than 2048-bit ElGamal.<br/>
521-bit <a href="http://en.wikipedia.org/wiki/Elliptic_curve_cryptography">ECC</a> is stronger than 256-bit ECC, but it makes Email Destinations longer.<br/>
2048-bit <a href="http://en.wikipedia.org/wiki/ElGamal">ElGamal</a> produces even longer Email Destinations, and it is the cryptographically weakest of the three options. However, ElGamal is better researched than ECC, which makes it less likely that there is an unknown weakness in ElGamal than in ECC.
<br>
</p>
<div class="date"></div>
<p>
<strong>What algorithms are used for symmetric encryption, and for hashing?</strong><br/>
<a href="http://en.wikipedia.org/wiki/Advanced_Encryption_Standard">AES-256</a> in
<a href="http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29">CBC</a> mode and <a href="http://en.wikipedia.org/wiki/SHA-2">SHA-256</a>.
</p>
<div class="date"></div>
<p>
<strong>Are there any anti-spam measures?</strong><br/>
I2P-Bote does no active spam filtering, but the fact that mass emails have to be sent individually should discourage spammers. Another line of defense is <a href="http://www.hashcash.org/">HashCash</a> which is supported at the protocol level and may be implemented in a future version if spam becomes a problem.
</p>
<div class="date"></div>
<p>
<strong>How about HTML or styled text?</strong><br/>
The webinterface does not render html.
</p>
<div class="date"></div>
<p>
<strong>How long are emails kept around?</strong><br/>
Emails are available for 100 days after they have been sent. Emails that have not been downloaded by then are deleted.<br/>
Emails you have received stay on your local machine until you delete them.
</p>
<div class="date"></div>
<p>
<strong>When do Email Identities expire?</strong><br/>
Never.
</p>
<div class="date"></div>
<p>
<strong>Can I send email to, and receive email from normal internet email servers?</strong><br/>
No, but this is being worked on.
<!-- Yes. You can both send and receive mails to/from ordinary internet e-mail accounts -->
</p>
<div class="date"></div>
<p>
<strong>Can I send email to, and receive email from postman's traditional I2P mail accounts?</strong><br/>
No, but this too is being worked on.
<!-- Yes. You can both send and receive mails to/from some_name@mail.i2p addresses -->
</p>
<div class="date"></div>
<p>
<strong>What does it mean when Know is x'ed for a mail in my inbox?</strong><br/>
When the sender's destination is not known locally the mail is marked by an x in the &#8220;Know&#8221; column
<!--or by putting &#8220;[UNK]&#8221; before the sender's address in POP3-->.<br/>
This means that you have no proof this user is really who he claims to be, in his user name. Of course, if the signature is valid, you know he possesses the destination key with which the mail was signed, and that the mail content is from that person. But you cannot rely on the short name here. In case you had gotten a mail from a user with this name before, you cannot be sure it is the same user this time, even if the signature is valid. In this
case you must compare the destination keys or add them to your addressbook. A user not locally known, is not necessarily evil, but you shouldn't trust it's the user you might think it is. But, if verified against locally stored keys, you know it's the same user when you receive another mail from him and &#8220;Know&#8221; has a green check.
</p>
<div class="date"></div>
<p>
<strong>What do &#8220;BktPfx&#8221;, &#8220;Distance&#8221; and &#8220;Locked?&#8221; mean?</strong><br/>
&nbsp; &bull; &nbsp; BktPfx = BucketPrefix<br>
&nbsp; &bull; &nbsp; Distance: the distance of an I2P-Bote node to your own node in keyspace<br>
&nbsp; &bull; &nbsp; Locked: If a node is not reachable for whatever reason, it is marked as locked, plus the time it has been found unreachable.<br>
</p>
<div class="date"></div>
<p>
<strong>What can I do to be more anonymous?</strong><br/>
<ul>
<li><p>Don't send identifying information about you! (name, address, photos, geographic location, time zone, age, sex, websites, login names, I2P router id, I2P-Bote id, Files that contain author information about you, &#8230;)</p></li>
<li><p>don't send personal information or information that only you can possess,</p></li>
<li><p>leave I2P-Bote running 24/7,</p></li>
<li><p>use mailroutes with randomized per-hop delays and/or per-hop fixed send times, <font color="#ff0000">[not yet fully implemented]</font></p></li>
<li><p>use a long check interval,</p></li>
<li><p>use a long local delay for own packets,</p></li>
<li><p>use a big check interval randomization. <span style="color: red;">[not yet implemented]</span></p></li>
<li><p>suppress the sending of date and time in the e-mails' header,</p></li>
<li><p>suppress translation of markers like &#8220;Re:&#8221; into another language,</p></li>
<li><p>watch your language and writing style,</p></li>
<li><p>use different e-mail identities,</p></li>
<li><p>consider discarding e-mail identities after longer periods of usage,</p></li>
<li><p>...</p></li>
</ul>
</p>
<div class="date"></div>
<p>
<strong>How do I not send timestamps?</strong><br/>
Go to settings and disable sending of timestamps. This will have the effect that your mail will not contain a date or time of sending.
<!-- <br/>(When using mailroutes, the timestamps are automatically disabled.) <span style="color: red;">[not yet implemented]</span></p> -->
</p>
<div class="date"></div>
<p>
<strong>How do I migrate my settings and data to another computer, or back them up?</strong><br/>
I2P-Bote stores all email and other data in the <tt>i2pbote</tt> folder. On Windows, that folder can be found at
<tt>%APPDATA%\I2P\i2pbote</tt>; on Linux, it is <tt>$HOME/.i2p/i2pbote</tt>.<br/>
To back up or migrate everything, just copy the whole <tt>i2pbote</tt> folder.<br/>
If you are only interested in your Email Identities, copy the file <tt>identities.txt</tt>. For the address book, copy <tt>addressBook.txt</tt>.
</p>
<div class="date"></div>
<p>
<strong>What is a <i>mail route?</i></strong><br/>
see: What does high-latency transport mean?<br/>
<!-- (When using mail routes, the timestamps are automatically disabled.) [yet to be implemented] -->
</p>
<div class="date"></div>
<p>
<strong>What does high-latency transport mean?</strong><br/>
It means that you can enable an option where e-mail packets are not sent directly to storing nodes, but are relayed (forwarded) by other peers (who cannot read the e-mails, as they are encrypted with several layers and ripped into small parts), who do not send them on immediately but wait a user-specified time &#8211; in case of sending
specified by the sender, in case of receiving specified by recipient.<br/>
Therefore it takes the mail some time to arrive. Thus an attacker cannot simply run stats on node uptimes (who was connected when) and times a message was received to be stored (which in a low-latency environment would be about the time it was sent), in order to uncover the real life identities behind I2P-Bote e-mail identities.
</p>
<div class="date"></div>
<p>
<strong>What latencies are there, and how can they be controlled (if at all)?</strong><br/>
I2P-Bote is distributed and running on top of the I2P network, so it takes some time. Speed is not our strength, but we compare well with other anon mail systems. Without mail routes enabled it takes 3 to 10 minutes from hitting the
&#8220;Send&#8221; button to being displayed in the receiver's inbox.<br/>
If speed is what you want, fully disable mail routes or set them to the minimum number of hops and minimum per-hop delay you can live with.
</p>
<div class="date"></div>
<p>
<strong>If I2P-Bote generates its own anonymity, why does it need I2P?</strong><br/>
I2P-Bote is built on top of I2P mainly for five reasons:<br/>
&nbsp; &bull; &nbsp; I2P was lacking a decentralized e-mail service and HungryHobo is an I2P user.<br/>
&nbsp; &bull; &nbsp; I2P offers very good anonymity, is mature and incorporates years of experience.<br>
&nbsp; &bull; &nbsp; So being on top of it, kind of represents an anonymity fall-back even if there were some crucial bugs in I2P-Bote.<br/>
&nbsp; &bull; &nbsp; Flexibility: We want to offer an easy way to anonymous low-latency e-mail communication as well, with still a high level of protection.<br/>
&nbsp; &bull; &nbsp; I2P with it the many other apps running on top of it creates a lot of traffic that blends with I2P-Bote traffic.<br/>
&nbsp; &bull; &nbsp; Even I2P-Bote relays are thus location-hidden.
</p>
<div class="date"></div>
<p>
<strong>How anonymous/secure is I2P-Bote without mail routes?</strong><br/>
Pretty anonymous and very secure.<br/>
It then basically enjoys the same anonymity other apps have on I2P, the anonymity provided by the I2P router &#8211; which is rather strong anonymity already. However, I2P is a low-latency network, with all the shortcomings a
low-latency network comes with by its very nature. There are attacks against which I2P cannot protect you or not protect you very reliably. I2P-Bote does its best to augment I2P anonymity with its high-latency transport option, which make &#8211; if enabled &#8211;
I2P-Bote mails <i>paranoidly</i> anonymous.
</p>
<div class="date"></div>
<p>
<strong>Is I2P-Bote open source?</strong><br/>
Of course!<br/>&#8220; <i>
This software is licensed under the GPL version 3 (see licenses/GPLv3.txt), except for bcprov-ecc-jdk16-145.jar which is licensed under the Bouncy Castle License
(see licenses/BouncyCastle.txt).</i>&#8221; <br>(Both of which are free open source licences.)
</p>
<div class="date"></div>
<p>
<strong>Who made I2P-Bote?</strong><br/>
(See also Credits!)<br>
Conception, technical design, implementation and web user interface were/are done by HungryHobo, an anonymous developer. For feedback or if you want to offer help, you can contact him using I2P-Bote. His destination key is: <br><b>hobo37SEJsEMfQHwcpVlvEgnrERGFz34GC1yjVyuRvl1QHnTi0UAoOtrLP~qkFY0oL59BBqj5sCep0RA8I5G8n</b>
</p>
<div class="date"></div>
<p>
<strong>What languages are available?</strong><br/>
English, German, Russian, French, Spanish, Portuguese, Dutch, Norwegian, Swedish, Chinese, and Arabic.
</p>
<div class="date"></div>
<p>
<strong>How can I help translate I2P-Bote into my language?</strong><br/>
Translations are done the same way as the rest of I2P. If you would like to help and have questions, please
<a href=contact.html>contact the author.</a>
</p>
<div class="date"></div>
<p>
<strong>How does it work on a technical level?</strong><br/>
Have a look at the file <tt>doc/techdoc.txt</tt> in the source code.
</p>
<div class="date"></div>
<p>
<strong>What are some other ways I can help?</strong><br/><br/>
&nbsp; &bull; &nbsp; Use I2P-Bote and give feedback<br/><br/>
&nbsp; &bull; &nbsp; Tell your friends, family, collegues et al. about I2P-Bote and lend them a hand<br/><br/>
&nbsp; &bull; &nbsp; Mention I2P-Bote on your blog, eepsite or website<br/><br/>
&nbsp; &bull; &nbsp; Write a user's guide or improve the technical documentation<br/><br/>
&nbsp; &bull; &nbsp; Add features or fix bugs (<a href=contact.html>contact the author first</a>)<br/><br/>
</p>
<div class="date"></div>
<p>
<br/><br/><br/><br/><br/><br/><br/>
<strong>Credits:</strong><br/><br/>
Idea &amp; technical concept: <i>HungryHobo</i>, <i>Mixxy</i><br/><br/>
Implementation: <i>HungryHobo</i><br/><br/>
Plugin support: <i>zzz</i>, <i>HungryHobo</i><br/><br/>
User interface: <i>HungryHobo</i><br/><br/>
Seedless integration: <i>sponge</i><br/><br/>
German translation: <i>HungryHobo</i><br/><br/>
Russian translation: <i>suhr</i><br/><br/>
French translation: <i>albat</i>, <i>Redzara</i>, <i>Mixxy</i><br/><br/>, <i>magma</i><br/><br/>
Spanish translation: <i>Mixxy</i><br/><br/>
Portuguese translation: <i>Mixxy</i><br/><br/>
Dutch translation: <i>KwukDuck</i><br/><br/>
Norwegian translation: <i>hej</i><br/><br/>
Swedish translation: <i>hottuna</i><br/><br/>
Chinese translation: <i>walking</i><br/><br/>
Arabic translation: <i>hamada</i><br/><br/>
Alpha testing: <i>HungryHobo</i>, <i>Mixxy</i>, <i>Returning Novice</i>, <i>sponge</i>, and many others<br><br/>
Manual: <i>Mixxy</i><br/><br/>
<br><br/>
</p>
<div class="date"></div>
</div>
</div>
<div id="footer">
<div class="rside">CSS: <a href="http://www.free-css-templates.com" title="Design by David Herreman">David Herreman</a></div>
<p>
<a href="http://validator.w3.org/check?uri=referer" title="Validate">XHTML</a> - <a href="http://jigsaw.w3.org/css-validator/check/referer" title="Validate">CSS</a>
</p>
</div>
</div>
</body>
</html>

View File

@ -1,622 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head>
<title>Foire aux questions</title>
<meta http-equiv="Content-Language" content="English">
<meta name="Robots" content="index,follow">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" type="text/css" href="FAQ_fr_files/style.html"
media="screen">
</head><body>
<div id="wrap">
<div id="top">
<div class="rights"> </div>
<div id="search">
</div>
<div class="lefts">
<h1>I2P-Bote</h1>
<h2>Messagerie décentralisée sécurisée</h2>
</div>
</div>
<div id="topmenu">
<div class="rights"></div>
<div class="lefts"><ul>
<li><a
href="http://t5qds7twb7eyyvp2fchhbn74tgdzv774rlru5guit5jkn4a6do7a.b32.i2p/index.html"
title="Home">Accueil</a></li>
<li><a
href="http://t5qds7twb7eyyvp2fchhbn74tgdzv774rlru5guit5jkn4a6do7a.b32.i2p/download.html"
title="Download I2P-Bote">Téléchargement</a></li>
<li><a
href="http://t5qds7twb7eyyvp2fchhbn74tgdzv774rlru5guit5jkn4a6do7a.b32.i2p/screenshots.html"
title="Screenshots">Captures d'écrans</a></li>
<li><a
href="http://t5qds7twb7eyyvp2fchhbn74tgdzv774rlru5guit5jkn4a6do7a.b32.i2p/userguide.html"
title="User Guide">Guide d'utilisation</a></li>
<li><a
href="http://t5qds7twb7eyyvp2fchhbn74tgdzv774rlru5guit5jkn4a6do7a.b32.i2p/faq.html"
title="Frequently Asked Questions">Foire aux questions</a></li>
<li><a href="http://forum.i2p/viewforum.php?f=35" title="Forum">Forum</a></li>
<li><a
href="http://t5qds7twb7eyyvp2fchhbn74tgdzv774rlru5guit5jkn4a6do7a.b32.i2p/contact.html"
title="Contact">Contact</a></li>
</ul></div>
</div>
<div style="text-align: justify;" id="main">
<div id="leftside">
<p>
</p><h2>Foire aux questions</h2>
<p>
</p><div class="date"></div>
<p>
<strong>I2P-Bote, kesako?</strong><br>
C'est un programme de messagerie P2P conçu pour protéger votre vie privée.<br>
I2P-Bote un système de messagerie entièrement décentralisé (sans serveur)
qui fonctionne sur le réseau I2P.
Il prend en charge les identités multiples et n'expose pas les
en-têtes de messages. Il est encore en phase de développement et n'est
accessible que via la console du routeur I2P. Il sera bientôt doté de la prise en
charge de POP3, et de plus d'anonymat via une option de transport
à haute latence. Tous les messages bote sont automatiquement
cryptés de bout en bout sans avoir à régler de cryptage de mails
(bien que cette option soit disponible), et ils sont authentifiés
automatiquement. Comme il est décentralisé, aucun serveur de mail ne peut
faire de rapprochement entre expéditeur et destinataire (profilage):
même les nœuds relayant les messages ne peuvent identifier l'expéditeur
et en dehors de expéditeur et du destinataire, seuls le point terminal du
tunnel à haute latence et les nœuds de stockage connaissent à qui (l'identité
anonyme) est destiné le message. L'expéditeur peut se déconnecter bien avant que
le message arrive à destination.
Ceci augmente encore le niveau d'anonymat que peut atteindre I2P-Bote.
Pour ceux qui ne veulent pas de forts délais, tous ces paramètre sont
modifiables pour s'adapter au niveau de leur besoin d'anonymat.
</p>
<div class="date"></div>
<p>
<strong>Pourquoi ce nom d'I2P-Bote?</strong><br>
Bote est le mot allemand pour dire "messager".
</p>
<div class="date"></div>
<p>
<strong>Pourquoi I2P-Bote?</strong><br>
Parce que c'est sympa. Et parce qu'un système décentralisé faisait cruellement
défaut et qu'I2P n'avait pas de système de messagerie décentralisé, et qu'y voyant
une opportunité d'améliorer un aspect négligé des considérations sur l'anonymat,
il fut décidé d'ajouter une méthode de transport à latence élevée.
Vous pourriez utiliser un compte de messagerie normal et crypter vos messages,
mais ils ne seraient pas pour autant anonymes. Vous pourriez alors utiliser un serveur
d'envoi anonyme, mais ils ne seraient pas automatiquement cryptés de bout en bout.<br>
Ou vous pouvez utiliser I2P-Bote grâce auquel vos messages sont anonymes et
<i>automatiquement</i> cryptés de bout en bout.<br> À la différence des messageries
traditionnelles, il n'y a pas à s'occuper de gérer en plus un système de clés. Tout
ce dont vous avez besoin est déjà prêt.<br> Et ne vous y trompez pas, malgré son
apparente simplicité et sa réelle facilité d'utilisation, I2P-bote vous offre un niveau
de cryptage de qualité militaire et des options d'anonymat extrêmement efficaces.
</p>
<div class="date"></div>
<p>
<strong>Que se passe-t-il quand je clique sur "Envoyer"?</strong><br>
Le message est crypté et stocké sur des ordinateurs d'autres utilisateurs d'I2P-Bote.
À partir de là, il est expédié au destinataire quand il relève son courrier.
</p>
<div class="date"></div>
<p>
<strong>Une minute! Tous mes envois sont stockés dans les ordinateurs de personnes
choisies aléatoirement? C'est une idée de fou!</strong><br>
Tout ce qu'elles peuvent voir n'est qu'un tas d'ordures car les données sont cryptée
à un niveau militaire. Seuls vous et le destinataire savez ce qu'il y a dans le
message. De plus, si vous envoyez en ayant activé le relayage, il ne leur est même pas
possible de savoir qui l'a envoyé.<br> Entre ça et l'utilisation d'un compte fourni par
une <a href="http://www.theregister.co.uk/2009/12/07/schmidt_on_privacy/">société
qui ne respecte pas votre vie privée</a>, sur une liaison Internet qui
<a href="http://www.eff.org/issues/nsa-spying">peut être espionnée par des entités
occultes</a>, quelle est la solution la plus digne de confiance?
</p>
<div class="date"></div>
<p>
<strong>Comment cela marche-t-il exactement?</strong><br>
Voyez le chapitre “Concept” du Guide <br>En bref:
Les nœuds I2P-Bote constituent un réseau p2p relayant les paquets de messages
pour le compte des autres et les stockant dans une table de hachage décentralisée (DHT).
</p>
<div class="date"></div>
<p>
<strong>Pourquoi devrais-je m'en servir? Je n'ai rien à cacher&hellip;</strong><br>
Vous vous baladez à poil dans la rue, vous?<br>Bon, après tout c'est possible. Mais il
faut quand même noter qu'il peut parfois vous arriver d'avoir des besoins de correspondances
épistolaires secrètes et intraçables, et ne pas faire savoir au monde entier que vous
dites ceci ou cela et à qui vous le dites.<br>
Parfois, vous pouvez aussi vouloir communiquer de façon entièrement anonyme avec
un tiers.<br>I2P-Bote est alors le moyen idéal qui vous donne une protection d'enfer
tout en restant très facile à utiliser.<br>
Il parvient à combiner une sécurité de niveau militaire et une ergonomie de niveau
débutant:<br>
vous pouvez avoir réglé un niveau d'anonymat paranoïaque, qui retardera l'arrivée du message
d'une demi-éternité, ou avoir des échanges plus rapides et cependant garder un fort
niveau d'anonymat.<br>
À vous de décider, d'un simple clic de souris.</p>
<div class="date"></div>
<p>
<strong>Et au sujet de <a href="http://www.pgp.com/">PGP</a> et
<a href="http://gnupg.org/">GPG</a>?</strong><br>
PGP et GPG vous permettent de crypter le courrier et de l'envoyer par votre compte de
messagerie existant. Il offrent du cryptage fort, mais uniquement du corps du message,
pas des en-têtes, ce qui veut dire que les champs "Objet", le nom de votre ordinateur,
et d'autres informations ne sont pas protégées.<br> Une autre faiblesse de PGP/GPG
est qu'ils ne peuvent pas empêcher de trouver qui parle à qui.<br>
I2P-Bote, au contraire, crypte tout sauf la destination (en fait, même la destination
n'est visible que par les nœuds qui ignorent de qui vient le message). Il peut aussi
envoyer le message via plusieurs relais (comme
<a href="http://mixmaster.sourceforge.net/">Mixmaster</a>), de sorte que personne ne
puisse trouver qui envoie à qui.<br>
</p>
<div class="date"></div>
<p>
<strong>Puis-je toujours utiliser GPG/PGP avec I2P-Bote?</strong><br>
Bien sûr. Cryptez le texte de votre message avec GPG avant de le coller dans le corps
du message I2P-Bote, ou utilisez une application de messagerie compatible GPG
[<font color="#ff0000">Prise en charge POP3 non implémentée</font>].
</p>
<div class="date"></div>
<p>
<strong>Quelle différence y a-t-il avec Susimail?</strong><br>
I2P-Bote est meilleur parce que son numéro de version est plus élevé&hellip; blague.<br>
I2P-Bote apporte plus d'anonymat, mais Susimail dispose de fonctionnalités dont
I2P-Bote est pour l'instant dépourvu (voir plus bas), et Susimail est plus efficace en
terme de consommation de bande passante car il ne fait pas de stockage redondant
réparti.
</p>
<div class="date"></div>
<p>
<strong>Pourquoi I2P-Bote est-il meilleur?</strong><br>
<i>Nous</i> pensons qu'il est meilleur&hellip; <i>pour nous</i> (et peut-être pour vous, aussi;
décidez vous-même!), que&hellip;</p><ul><li><p style="line-height: 150%;">
<font face="Arial, sans-serif">mixminion car il est facile à utiliser et aussi simple à prendre
en main que nous avons pu.</font></p>
</li><li><p style="line-height: 150%;"><font face="Arial, sans-serif">les services de mail
anonymes n'utilisant pas le routage basé sur des clés de destination, car ils ne permettent pas
le cryptage de bout en bout.</font></p>
</li><li><p style="line-height: 150%;"><font face="Arial, sans-serif">les services centralisés,
car que le serveur pourrait s'arrêter (à cause d'attaques, de problèmes légaux, manque de
financement ou d'intérêt&hellip;) et car l'administrateur du serveur dispose de trop de moyens
pour faire de l'espionnage.</font></p>
</li></ul>
<div class="date"></div>
<p>
<strong>Comment mon identité est-elle protégée quand j'échange du courrier?</strong><br>
Jamais votre adresse IP ni même votre destination I2P n'est inclue dans les messages que vous
envoyez.<br>
Les compteurs de transports à haute latence protègent des attaques de timing.<br>
Le cryptage de bout en bout et par saut, le relayage des paquets pour d'autres nœuds, les
paquets à taille unique* (bourrage/padding), le débit d'envoi constant (messages de test
et bidons/dummy)*, et un rapport assez équilibré des taux d'envoi/réception* protègent des
attaques d'analyse de trafic, et en combinaison avec les delais par saut, I2P-Bote offre de
bons moyens de prévention des attaques d'intersection.<br>
La nature open source d'I2P-Bote garantit que vous pouvez vous-même voir la mise en œuvre et
la vérifier pour y chercher ou trouver des bogues.
<br>*[<font color="#ff0000">pas encore implémenté</font>]</p>
<div class="date"></div>
<p>
<strong>Comment faire pour l'utiliser?</strong><br>
Lisez le Guide ou les autres questions/réponses ici!<br>
Si vous avez toujours des questions, posez-les sur le forum:
<a href="http://forum.i2p/viewforum.php?f=35">http://forum.i2p/viewforum.php?f=35</a>
</p>
<div class="date"></div>
<p>
<strong>Puis-je utiliser un programme comme Thunderbird?</strong><br>
Non, mais c'est sur la feuille de route.
<!--Yes, you can use the e-mail client of your choice, as long as it supports POP3 and
SMTP<br/>[<font color="#ff0000">POP3 and SMTP not yet implemented</font>]-->
</p>
<div class="date"></div>
<p>
<strong>Puis-je envoyer des pièce-jointes, et quelles sont les limites?</strong><br>
Oui, depuis la version 0.2.5.<br>La taille cumulée des pièces jointes devrait être petite et de
préférence ne pas dépasser les 500ko.</p>
<div class="date"></div>
<p>
<strong>Comment créer un compte de messagerie?</strong><br>
I2P-Bote les appelle "Identités". Vous pouvez en créer une dans l'interface web d'I2P-Bote
via le lien "Identités". La raison pour laquelle on ne les appelle pas "comptes" est qu'il
n'y a pas de fournisseur comme GMail ou autre. Vous êtes le seul dépositaire du porte-clés
(cryptographique) de l'identité.<br>Quand vous la créez, I2P-bote génère une chaîne de
chiffres et de lettres appelée "Destination". C'est l'adresse à laquelle on peut vous joindre.
<br>
Exemple: <tt><b>wsq-8u5bTWbaOsrS0JuXRKL-RsbTkckV4W7u2mIu0Yrlfetixq1F~03CArnvbd6tDWwjPHYEuoKyWqwxplSdix</b></tt>
</p>
<div class="date"></div>
<p>
<strong>Qu'est-ce qu'une destination? Et l'adresse mail?</strong><br>
La longueur des destinations est comprise entre 86 et 512 caractères, suivant le type de
cryptage. La prise en charge d'adresses faciles à mémoriser et choisies par l'utilisateur est
au programme d'un futur proche.<br>Les identités sont une paire de clés privée et publique,
et d'un nom que l'utilisateur lui attribue. La clé publique est la destination,
votre identité pseudonymique. Un utilisateur réel peut en avoir plusieurs. Elles servent à
envoyer des messages à certains utilisateurs donc aussi appelés “destinations” tout comme
pour crypter les messages qui leur sont&hellip; destinés. Votre destination est donc pour les
autres aussi la clé qu'ils utilisent pour crypter les messages qu'ils vous envoient et pour
pour vérifier l'intégrité et l'authenticité de ceux qu'ils reçoivent&hellip; de vous.<br>
Il est sans danger (et indispensable) de donner votre destination à toute personne de laquelle
vous voulez recevoir du courrier.<br>Il est important de faire la distinction entre votre
destination de messagerie et la destination de votre routeur I2P! Votre identité de messagerie
n'a rien à voir avec l'identité de votre nœud/routeur I2P-Bote qui est utilisée pour permettre
aux nœuds I2P-Bote de se contacter les uns les autres pour constituer le réseau Bote.<br>
Si vous avez des problèmes avec l'application I2P-Bote dans le cas très improbable où ça
serait nécessaire vous pouvez indiquer votre destination (au sens d'application I2P) sur
irc2p, les canaux IRC ou le forum I2P, ou ajouter manuellement des identités d'autres pairs
pour pouvoir vous connecter, bien que ceci n'ait jamais été nécessaire à ce jour.<br>
Elle <b>n'est pas liée à votre adresse IP</b>. Néanmoins, ne révélez d'aucune façon la relation
entre votre identité de routeur I2P-Bote et celle d'une de vos propres destinations de courrier
I2P-Bote car cela réduirait à néant le niveau d'anonymat supplémentaire qu'I2P-Bote porte en
lui-même!
</p>
<div class="date"></div>
<p>
<strong>Pourquoi les adresses sont-elles si longues?</strong><br>
Dans I2P-Bote chaque message est (automatiquement) crypté. Pour vous éviter d'avoir à échanger
votre adresse <b>ET</b> de très longues clés publiques, on a simplement fait de ces clés les
adresses. Deux autres avantages en découlent: vous n'avez pas à vous soucier de la préexistence
de votre adresse (au moins tant que vous ne recevez ni n'envoyez courrier vers
l'Internet normal), et vous n'avez pas à avoir un système de gestion de clés séparé pour
s'occuper de vos clés.<br>
Il est sans danger (et indispensable) de donner cette clé, car elle n'est que la clé publique,
que certains peuvent avoir à connaître, sans pour autant que cela compromette la
confidentialité de vos messages.<br>
L'utilisation du cryptage ECC conduit à des clés plus courtes.
</p>
<div class="date"></div>
<p>
<strong>Mais je n'arrive pas à mémoriser de si longues destinations&hellip;</strong><br>
Le carnet d'adresses est là pour ça. Une fois convaincu par le principe d'I2P-Bote, vous
apprécierez le cryptage et l'authentification intégrés, qui ne peuvent être atteints que par
l'utilisation de clés cryptographiques.
<br>Encore une fois, l'alternative serait d'avoir des adresses courtes et simples <b>plus</b>
de longues clés de cryptage et authentification, <b>ET</b> de se reposer sur quelqu'autorité
pour faire la relation entre l'adresse et un destinataire anonyme.
</p>
<div class="date"></div>
<p>
<strong>Quel est l'intérêt d'utiliser de multiples identités?</strong><br>
I2P-Bote n'est pas une messagerie instantanée, donc vous pouvez avoir plusieurs identités sans
avoir à tenir plusieurs tunnels ouverts en même temps. Vous utiliserez seulement un peu plus de
ressources au moment de la relève mais en même temps vous fournirez une meilleure couverture
aux autres.<br>
Maintenant, imaginez que vous communiquez incognito avec des amis (voir: lois sur le stockage
de données) via I2P-Bote, et que vous voulez envoyer rapidement un message pour vous retrouver
ce soir ailleurs qu'à l'habituel Café des Arts. Vous n'avez pas besoin d'un super-anonymat et
pouvez renoncer aux relayages et délais de mails. Vos amis, d'autre part, devraient raccourcir
leur intervalle de vérification pour recevoir le message à temps. Mais pour d'autres types de
communications, vous avez besoin d'un super niveau d'anonymat, <!--et c'est là qu'une autre
identité avec un relayage et des délais différents peut être utile-->
</p>
<div class="date"></div>
<p>
<strong>Quel est le meilleur cryptage?</strong><br>
<a href="http://fr.wikipedia.org/wiki/Cryptographie_sur_les_courbes_elliptiques">ECC</a> à 256
bits produit des adresses destinations courtes et maniables, et est considéré comme plus solide
que l'ElGamal à 2048 bits.<br>
<a href="http://en.wikipedia.org/wiki/Elliptic_curve_cryptography">ECC</a> à 521 bits est plus
solide que sa version à 256 bits, mais il génère des destinations (clés) très longues.<br>
<a href="http://fr.wikipedia.org/wiki/Cryptosyst%C3%A8me_de_ElGamal">ElGamal</a> à 2048 bits
génère des clés encore plus longues, et il est le plus faible des trois algorithmes. Cependant,
ElGamal fait l'objet de plus recherches que ECC, ce qui rend moins probable qu'une faiblesse de
cet algorithme passe inaperçue pendant plus longtemps que dans ECC.<br>
</p>
<div class="date"></div>
<p>
<strong>Quels algorithmes sont-ils utilisés pour le cryptage symétrique et le hachage?</strong><br>
<a href="http://fr.wikipedia.org/wiki/Advanced_Encryption_Standard_process">AES</a>-
<a href="http://fr.wikipedia.org/wiki/Advanced_Encryption_Standard">256</a> en mode
<a href="http://fr.wikipedia.org/wiki/Mode_d%27op%C3%A9ration_%28cryptographie%29#Encha.C3.AEnement_des_blocs_:_.C2.AB_
Cipher_Block_Chaining_.C2.BB_.28CBC.29">CBC</a> et
<a href="http://http://fr.wikipedia.org/wiki/Secure_Hash_Algorithm">SHA-256</a>.
</p>
<div class="date"></div>
<p>
<strong>Y a-t-il des protections anti-spam?</strong><br>
I2P-Bote ne filtre pas le spam, mais le fait que l'envoi en masse doive être fait
individuellement devrait décourager les spammers. Un autre moyen de défense repose sur des
pénalités (<a href="http://www.hashcash.org/">HashCash</a>) qui sont un mécanisme supporté au
niveau du protocole, et qui pourrait être implémenté dans une version ultérieure si le spam
devenait un problème.
</p>
<div class="date"></div>
<p>
<strong>Deux mot sur HTML et le formatage de texte?</strong><br>
L'interface web ne restitue pas la mise en forme HTML.
</p>
<div class="date"></div>
<p>
<strong>Pendant combien de temps les messages restent-ils dans la nature?</strong><br>
Ils restent disponibles 100 jours après l'émission. Les messages n'ayant pas été relevés
au-delà de cette période sont supprimés.<br>
Les messages relevés restent sur votre ordinateur jusqu'à ce que vous les supprimiez.</p>
<div class="date"></div>
<p>
<strong>Quand les identités expirent-elle?</strong><br>
Jamais. Mais la votre peut devenir inutilisable si vous perdez le contenu de votre disque dur.
Vous seriez alors amené à en créer une ou plusieurs autres en remplacement, et en informer vos
correspondants habituels.
</p>
<div class="date"></div>
<p>
<strong>Puis-je recevoir et envoyer des messages de/vers des serveurs de l'Internet normal?
</strong><br>
Non, mais on y travaille.
<!-- Yes. You can both send and receive mails to/from ordinary internet e-mail accounts -->
</p>
<div class="date"></div>
<p>
<strong>Et de/vers les comptes traditionnels de postman?</strong><br>
Non plus, mais on y travaille aussi.
<!-- Yes. You can both send and receive mails to/from some_name@mail.i2p addresses -->
</p>
<div class="date"></div>
<p>
<strong>Que signifient les icônes dans la colonne "Connu" de la boîte de réception?</strong><br>
Quand la destination expéditrice est inconnue localement le message est marqué d'un X dans la
colonne "Connu"
<!--or by putting &#8220;[UNK]&#8221; before the sender's address in POP3-->.<br>
Cela veut dire que vous n'avez aucune preuve que cet utilisateur est vraiment qui il prétend
être dans son nom public "humain". Bien sûr, si la signature est valide, vous êtes assuré(e)
qu'il possède la clé privée de destination avec laquelle il a signé le message, et donc que le
contenu du message est bien issu de cette personne. Mais vous ne pouvez pas vous fier au nom
court malgré tout (il vous faudrait un autre moyen de vous en assurer: qu'il vous ait remis sa
destination en main propre par exemple, ou vérifiée au téléphone, etc&hellip;). Dans le cas où
vous avez déjà eu un message d'un utilisateur affichant ce nom, vous ne pouvez pas être sûr(e)
que c'est le même utilisateur cette fois, même si la signature est valide. Dans ce cas, vous
devez comparer les clés de destination ou les ajouter à votre carnet d'adresses. Un utilisateur
inconnu localement n'est pas forcément une vermine, mais vous ne devriez pas lui faire
confiance à priori sur la seule foi du nom qu'il annonce. Mais s'il passe avec succès le test de
comparaison avec la clé précédemment par vous stockée localement, vous avez au moins la preuve
qu'il s'agit bien du même utilisateur quand vous recevez un nouveau message de sa part, et la
colonne "Connu" est maintenant décorée d'une jolie coche verte.
</p>
<div class="date"></div>
<p>
<strong>“BktPfx”, “Distance” et “Verrouillé?"&hellips; c'est quoi?</strong><br>
&nbsp;&nbsp; BktPfx = BucketPrefix (préfixe de paquet)<br>
&nbsp;&nbsp; Distance: la distance d'un nœud I2P-Bote au votre propre dans l'espace de clés.
<br>
&nbsp;&nbsp; Verrouillé: si un nœud n'est pas joignable, quelle qu'en soit la raison, il est
marqué "Verrouillé", et le temps depuis lequel sa défection a été découverte est affiché.<br>
</p>
<div class="date"></div>
<p>
<strong>Comment rester plus anonyme?</strong><br>
</p><ul>
<li><p>N'envoyez aucune information à votre sujet! (nom, adresse, photos, situation
géographique, fuseau horaire, âge, sexe, sites web, identifiants, id de routeur I2P, id
I2P-Bote, fichiers contenant des informations sur l'auteur, &hellip;)</p></li>
<li><p>N'envoyez pas d'information personnelles c'est à dire des informations qui vous
identifient de façon unique en tant que vous seul les connaissez,</p></li>
<li><p>Laissez I2P-Bote tourner 24/24 7/7,</p></li>
<li><p>Utilisez des routes de messages avec des délais aléatoires par-saut et/ou des temps
fixes par saut <font color="#ff0000">[not yet fully implemented]</font>,</p></li>
<li><p>Utilisez de longs intervalles de relève,</p></li>
<li><p>Utilisez un délais long pour vos propres paquets,</p></li>
<li><p>Utilisez un fort niveau d'intervalle de relève aléatoire. <span style="color:
red;">[not yet implemented]</span></p></li>
<li><p>Supprimez l'envoi de la date et de l'heure dans les en-têtes de messages,</p></li>
<li><p>Renoncez aux marqueurs de suivi tels que “Tr:” traduits dans votre langue,</p></li>
<li><p>Surveillez votre style de langage et d'écriture,</p></li>
<li><p>Utilisez différentes identités,</p></li>
<li><p>Envisagez d'abandonner vos identités après de longues périodes d'utilisation,</p></li>
<li><p>...</p></li>
<li><p>Cette liste n'est pas destinée à vous rendre paranoïaque, mais à vous montrer par où
l'anonymat peut-être amoindri.</p></li>
</ul>
<div class="date"></div>
<p>
<strong>Comment ne pas envoyer de tampons horaires?</strong><br>
L'option est dans les "Préférences". Les messages n'auront pas de date/heure d'envoi;
<!-- <br/>(When using mailroutes, the timestamps are automatically disabled.)
<span style="color: red;">[not yet implemented]</span></p> -->
</p>
<div class="date"></div>
<p>
<strong>Comment migrer mes réglages et données vers un autre ordinateur, ou les
sauvegarder?</strong><br>
I2P-Bote stocke tout le courrier et autres données dans le dossier <tt>i2pbote</tt>. Sur
Windows, <tt>%APPDATA%\I2P\i2pbote</tt>; sur Linux, <tt>$HOME/.i2p/i2pbote</tt>.<br>
Une simple copie du dossier <tt>i2pbote</tt> fait l'affaire.<br>
Si seules vos identités vous intéressent, copiez le fichier <tt>identities.txt</tt>.
Pour le carnet d'adresses, copiez <tt>addressBook.txt</tt>.
</p>
<div class="date"></div>
<p>
<strong>qu'est-ce qu'une <i>route de messages</i>?</strong><br>
voir: Que signifie "Transport à haute latence"?<br>
<!-- (When using mail routes, the timestamps are automatically disabled.) [yet to be implemented] -->
</p>
<div class="date"></div>
<p>
<strong>Que signifie "Transport à haute latence"?</strong><br>
Cela signifie que (par une option que vous pouvez activer) les paquets de messages ne sont pas
envoyés directement aux nœuds de stockage, mais sont relayés (transférés) par d'autres pairs
(qui ne peuvent pas les lire car ils sont cryptés sur plusieurs niveaux et découpés en petits
morceaux) qui ne les traitent pas immédiatement mais attendent un certain temps défini au
niveau utilisateur pour l'envoi, par l'expéditeur, pour la réception, par le destinataire.<br>
En conséquence le message est long à arriver. L'attaquant ne peut pas utiliser de statistiques
sur les temps de fonctionnement des nœuds (qui s'est connecté à quel moment) ni les moments où
un message a été reçu pour être stocké (ce dans un environnement à faible latence serait à peu
près le moment où il a été envoyé), pour en déduire les identités réelles sous-jacentes aux
identités I2P-Bote.
</p>
<div class="date"></div>
<p>
<strong>Quelles latences y a-t-il, et comment les contrôler?</strong><br>
I2P-Bote est décentralisé et s'exécute sur le reéseau I2P, donc ça prend du temps. La vitesse
n'est pas notre force, mais il supporte bien la comparaison à d'autres systèmes de messagerie
anonyme. Sans apport des routes de messages, il faut 3 à 10 mn entre le clic sur "Envoyer" et
l'affichage chez le destinataire.<br>Si la vitesse vous préoccupe, désactivez les routes ou
réglez-les au nombre de sauts et de retard par saut minimums avec lesquels vous pouvez vivre.
</p>
<div class="date"></div>
<p>
<strong>Si I2P-Bote son propre anonymat, pourquoi a-t-il besoin d'I2P?</strong><br>
I2P-Bote est bâti sur I2P pour cinq raisons principales:<br>
&nbsp;&nbsp; I2P manquait d'une messagerie décentralisée et HungryHobo est un utilisateur
d'I2P.<br>
&nbsp;&nbsp; I2P offre un excellent anonymat, il est bien au point et bénéficie de
nombreuses années d'expérience.<br>
&nbsp;&nbsp; Donc, en faire ses fondations représente une assurance d'anonymat s'il y avait
des bogues critiques dans I2P-Bote.<br>
&nbsp;&nbsp; Souplesse: nous voulons aussi offrir une méthode de communication à faible
latence, tout en gardant un haut niveau de protection.<br>
&nbsp;&nbsp; I2P, avec toutes les autres applications qui l'utilisent, génère beaucoup de
trafic dans lequel le trafic I2P-Bote peut se camoufler.<br>
&nbsp;&nbsp; En conséquence, même les relais I2P-Bote sont masqués en terme de localisation.
</p>
<div class="date"></div>
<p>
<strong>Que valent l'anonymat et la sécurité d'I2P-Bote sans les routes?</strong><br>
Plutôt bonne pour l'anonymat et très sécurisé.<br>
Il bénéficie de base du même anonymat que les autres applications I2P, l'anonymat procuré par
le routeur 2P router qui est déjà fort conséquent. Cependant, I2P est un réseau à faible
latence, avec tous les défauts intrinsèques de ce genre de réseaux. Il a des attaques contre
lesquelles I2P ne peut pas vous protéger ou au moins très efficacement. I2P-Bote améliore
l'anonymat grâce à ses options de transport à haute latence, qui rendent si vous les
activez les messages I2P-Bote à un niveau d'anonymat <i>paranoïaque</i>.
</p>
<div class="date"></div>
<p>
<strong>I2P-Bote, open source?</strong><br>
Bien sûr!<br><i>Ce logiciel est sous licence GPL version 3 (voir licenses/GPLv3.txt),
sauf pour bcprov-ecc-jdk16-145.jar qui est sous licence Bouncy Castle (voir
licenses/BouncyCastle.txt).</i><br>(Toutes deux sont des licences libres et ouvertes).
</p>
<div class="date"></div>
<p>
<strong>Qui a créé I2P-Bote?</strong><br>
(Voir aussi les "Remerciements"!)<br>
La conception, la structure technique, l'implémentation et l'interface web user sont de
HungryHobo, un développeur anonyme. Pour les retours techniques ou proposer votre aide, vous
pouvez le contacter avec I2P-Bote. Sa destination est: <br>
<b>hobo37SEJsEMfQHwcpVlvEgnrERGFz34GC1yjVyuRvl1QHnTi0UAoOtrLP~qkFY0oL59BBqj5sCep0RA8I5G8n</b>
</p>
<div class="date"></div>
<p>
<strong>Langues disponibles</strong><br>
Anglais, allemand, russe, français, espagnol, portugais, hollandais, norvégien, suédois,
chinois et arabe.
</p>
<div class="date"></div>
<p>
<strong>Comment puis-je aider à la traduction d'I2P-Bote dans ma langue?</strong><br>
Comme pour I2P.
<a href="http://t5qds7twb7eyyvp2fchhbn74tgdzv774rlru5guit5jkn4a6do7a.b32.i2p/contact.html">
Contactez l'auteur.</a>
</p>
<div class="date"></div>
<p>
<strong>Fonctionnement technique?</strong><br>
Regardez <tt>doc/techdoc.txt</tt> dans le code source.
</p>
<div class="date"></div>
<p>
<strong>D'autres moyens pour aider?</strong><br><br>
&nbsp;&nbsp; Utilisez I2P-Bote et faites part de vos commentaires/<br><br>
&nbsp;&nbsp; Parlez d'I2P-Bote à vos amis, à votre famille et à vos collègues, et aidez-les.
<br><br>
&nbsp;&nbsp; Mentionnez I2P-Bote sur votre blog, votre eepsite et votre web.<br><br>
&nbsp;&nbsp; Rédigez un guide utilisateur ou améliorez la documentation technique.<br><br>
&nbsp;&nbsp; Ajoutez des fonctionnalités ou corrigez des bogues (<a
href="http://t5qds7twb7eyyvp2fchhbn74tgdzv774rlru5guit5jkn4a6do7a.b32.i2p/contact.html">contactez tout d'abord l'auteur
</a>).<br><br>
</p>
<div class="date"></div>
<p>
<br><br><br><br><br><br><br>
<strong>Remerciements:</strong><br><br>
Idée &amp; conception technique: <i>HungryHobo</i>, <i>Mixxy</i><br><br>
Implémentation: <i>HungryHobo</i><br><br>
Maintenance du greffon: <i>zzz</i>, <i>HungryHobo</i><br><br>
Interface utilisateur: <i>HungryHobo</i><br><br>
Intégration de Seedless: <i>sponge</i><br><br>
Traduction allemande: <i>HungryHobo</i><br><br>
Traduction russe: <i>suhr</i><br><br>
Traduction française: <i>albat</i>, <i>Redzara</i>, <i>Mixxy</i>, <i>magma</i><br><br>
Traduction espagnole: <i>Mixxy</i><br><br>
Traduction portugaise: <i>Mixxy</i><br><br>
Traduction hollandaise: <i>KwukDuck</i><br><br>
Traduction norvégienne: <i>hej</i><br><br>
Traduction suédoise: <i>hottuna</i><br><br>
Traduction chinoise: <i>walking</i><br><br>
Traduction arabe: <i>hamada</i><br><br>
Testeurs versions Alpha: <i>HungryHobo</i>, <i>Mixxy</i>, <i>Returning Novice</i>,
<i>sponge</i>, et de nombreux autres<br><br>
Manuel: <i>Mixxy</i><br><br>
<br><br>
</p>
<div class="date"></div>
</div>
</div>
<div id="footer">
<div class="rside">CSS: <a href="http://www.free-css-templates.com/"
title="Design by David Herreman">David Herreman</a></div>
<p>
<a href="http://validator.w3.org/check?uri=referer" title="Validate">XHTML</a>
- <a href="http://jigsaw.w3.org/css-validator/check/referer"
title="Validate">CSS</a>
</p>
</div>
</div>
</body></html>

View File

@ -1,879 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html><head>
<meta content="text/html; charset=ISO-8859-1" http-equiv="content-type"><title>User's Guide</title><meta http-equiv="CONTENT-TYPE" content="text/html; charset=utf-8"><meta name="GENERATOR" content="OpenOffice.org 3.2 (Unix)"><style type="text/css">
<!--
@page { margin: 2cm }
P { margin-bottom: 0.21cm }
A:link { so-language: zxx }
-->
</style><meta http-equiv="CONTENT-TYPE" content="text/html; charset=utf-8"><meta name="GENERATOR" content="OpenOffice.org 3.2 (Unix)"><style type="text/css">
<!--
@page { margin: 2cm }
P { margin-bottom: 0.21cm }
-->
</style></head><body>
<p style="line-height: 150%; font-weight: bold;" align="center"><font face="Arial, sans-serif">I2P-Bote
Manual</font></p>
<p style="line-height: 150%;"><br></p>
<p style="line-height: 150%;"><br>
</p>
<p style="line-height: 150%;"><font face="Arial, sans-serif"><b>1.
Introduction</b></font></p>
<p style="line-height: 150%;"><br><br>
<font face="Arial, sans-serif">I2P-Bote
is an easy-to-use, highly anonymous secure e-mail application for
I2P. It is a serverless, fully decentralized system that
establishes/forms a peer-to-peer network built on top of
state-of-the-art low latency anonymizing network I2P; adding to it an
optional mixminion-like high-latency transport and thus avoiding the
shortcomings of low-latency networks.</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">Therefore,
I2P-Bote makes full use of the anonymity provided by I2P, plus it
generates its own anonymity by adding another anonymizing layer
(overlay network).</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">This
concept of layered anonymity is what makes I2P-Bote so flexible:</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">You can
configure it to be extremely anonymous and slow or less anonymous but
faster/more efficient. In any event, I2P-Bote<font color="#000000">
always provides a very good anonymity for both, sender and receiver,
as well as end-to-end encryption*. </font></font>
</p>
<p style="line-height: 150%;"><font color="#000000"><font face="Arial, sans-serif">I2P-Bote
offers the option to make your communications even more anonymous, by
enabling the high-latency mail routes &#8211; at cost of performance,
however. Users that want their anonymous e-mails to arrive as quickly
as possible, will want to disable the mail routes and use 'direct'
sending through I2P. It is guaranteed that you will never be less
anonymous than the anonymity provided by standard I2P connections. </font></font>
</p>
<p style="line-height: 150%;"><font face="Arial, sans-serif"><font color="#000000">In
order to achieve high usability, we have enabled it to be used with
standard mail clients such as Thunderbird, Evolution or Kmail,
without having to worry about what extra information these
applications send in their headers. [</font><font color="#ff0000">YET
TO BE IMPLEMENTED</font><font color="#000000">] Furthermore there is
a web interface that lets you send and read e-mails or manage your
settings and identities.</font></font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">I2P-Bote
is easy to use: If you're
not yet using I2P, just install I2P from <a href="http://www.i2p2.de/">http://www.i2p2.de</a>
and then install the I2P-Bote plugin as described in this manual.
Otherwise simply read on!**</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif"><i>Current
version is 0.2.6.</i></font><br><br>
</p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">*Unless
you send e-mails to or receive them from the regular internet, ALL
emails &#8211; the mail body, attachments and the header except
recipient's address (subject, date, time, sender address, ...) are
automatically and transparently end-to-end encrypted. The recipient's
address is only visible for the mail route's last node that stores
the packets into the kad network, and the respective storing nodes,
but they cannot read the mail's content nor who sent it nor who will
fetch it.</font></p>
<p style="line-height: 150%;"><br><br>
</p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">**Of
course you can also compile from source.</font></p>
<p style="line-height: 150%;"><br>
</p>
<p style="line-height: 150%;"><br>
<br>
</p>
<p style="line-height: 150%;"><font face="Arial, sans-serif"><b>2.
Howto</b></font></p>
<p style="line-height: 150%;"><br>
</p>
<p style="line-height: 150%;"><font face="Arial, sans-serif"><u>2.1.
Installation</u></font></p>
<p style="line-height: 150%;"><br>
</p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">In order
to install I2P-Bote, go to the bottom of the I2P Client Configuration
page at </font>
</p>
<p style="line-height: 150%;"><font face="Arial, sans-serif"><a href="http://localhost:7657/configclients.jsp">http://localhost:7657/configclients.jsp</a>
</font>
</p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">and
enter:</font></p>
<p style="line-height: 150%;"><a href="http://tjgidoycrw6s3guetge3kvrvynppqjmvqsosmtbmgqasa6vmsf6a.b32.i2p/i2pbote.xpi2p"><font face="Arial, sans-serif">http://tjgidoycrw6s3guetge3kvrvynppqjmvqsosmtbmgqasa6vmsf6a.b32.i2p/i2pbote.xpi2p</font></a></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">(
<a href="http://i2pbote.i2p/i2pbote.xpi2p">http://i2pbote.i2p/i2pbote.xpi2p</a>
might work, too, if you have i2pbote.i2p in your address book or a
subscription )</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">in the
&#8220;Plugin Installation Download Url&#8221; line, then hit &#8220;Install
Plugin&#8221;. Wait
until your sidebar says plugin installed and started. </font>
</p>
<p style="line-height: 150%;"><br>
</p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">In order
to update your I2P-Bote instance, click 'Update' under I2P-Bote on
the I2P Client Configuration page at
<a href="http://localhost:7657/configclients.jsp">http://localhost:7657/configclients.jsp</a></font></p>
<p style="line-height: 150%;"><br><br>
</p><p style="line-height: 150%;"><font face="Arial, sans-serif"><u>2.2.
Using I2P-Bote</u></font></p>
<p style="line-height: 150%;"><br><font face="Arial, sans-serif">On your
router console <a href="http://127.0.0.1:7657/">http://127.0.0.1:7657/</a>
click on <span style="font-style: italic;">SecureMail</span> on the upper left (in the sidebar). Now you are
on I2P-Bote's web interface.</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">After
starting I2P-Bote (by default it is set to start automatically when
your I2P router starts up) it takes a bit more than three minutes for
everything to be up and running. </font>
</p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">So have a
look at 'Network Status' on the left. It should state 'Connected'.</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">If you
want to use I2P-Bote for yourself, you first need to create an
identity.</font>
</p>
<p style="line-height: 150%;"><br><br>
</p>
<p style="line-height: 150%;"><font face="Arial, sans-serif"><u>2.2.1
Creating an Identity</u></font></p>
<p style="line-height: 150%;"><br><font face="Arial, sans-serif">Click on
'Identities' on the left, then hit the &#8220;New Identity&#8221; button.</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">Enter at
least a 'Public Name' and hit 'Create'. That's all that's needed to
create an identity.</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">The
public name is the name you see for this identity (useful in case you
have different identities for different sets of users you communicate
with or different purposes) and it will be sent as &#8220;sender's name&#8221;
to the mail's recipient. There is no need for Public Name to be
unique. </font>
</p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">(As you
can choose any name here &#8211; anyone could call himself HungryHobo
there &#8211; it is not suited to be used by the recipient for telling if
two mails come from the same sender. This is why the name saved in
the local addressbook (there can only by one name per destination
key) is displayed, if there is any, and you will see a green mark in
the &#8220;Know&#8221; column, stating it is the locally known name. If there
is no entry for a destination in local addressbook, the name
specified by the sender will be displayed with a prefixed [UNK] in
the mail clients). [<font color="#ff0000">POP3 NOT YET IMPLEMENTED</font>]</font></p>
<p style="line-height: 150%;"><br><font face="Arial, sans-serif">You can
also fill out the other fields, if you like:</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">Description
&#8211; this field is kept locally. It's just for your convenience: If
you want to add some additional information for yourself about that
identity, you can enter it here. </font>
</p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">Email
Address &#8211; this field is not used yet.<font color="#ff0000"><br></font></font><br><font color="#000000"><font face="Arial, sans-serif">Choose
from one of the given encryption algorithms. If in doubt, stick to
the defaults.</font></font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">You click
on the name of one of your identities and copy the long key displayed
under 'Email Destination'. This is your I2P-Bote e-mail address. If
you want anybody to be able to send you a bote mail, he need to be
given this long key.</font><br>
<br><font face="Arial, sans-serif">Now you
can send and receive I2P-Bote mails.</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">But you
should also have a look at your I2P-Bote settings and see if they fit
your needs.</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">(You can
also create various identities and assign different settings to each
of them.)</font></p>
<p style="line-height: 150%;"><br></p><p style="line-height: 150%;"><font face="Arial, sans-serif"><u><br>
2.2.2
Sending and Receiving E-Mails</u></font></p>
<p style="line-height: 150%;"><br>
</p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">You need
to have the I2P-Bote e-mail destination key of the user you to whom
you want to send a bote mail. </font>
</p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">In order
to send a message, click on 'New', choose your own sender identity or
'Anonymous' under &#8220;From&#8221; and enter the recipient's e-mail
destination key or alternatively an address in the &#8220;To:&#8221; line.</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">Alternatively,
you can hit the &#8220;Addr. Book&#8221; button right under this very line,
in order to chose from e-mail dests stored locally in your address
book: Mark the user(s) to which you want your mail to be sent and hit
the &#8220;Add Recipients&#8221; button.)</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">You can
add several recipients and change the 'To:' to 'CC:' or 'BCC:'.</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">The &#8220;+&#8221;
button adds additional recipient lines.</font></p>
<p style="line-height: 150%;"><br>
</p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">Now write
your bote mail and hit 'Send' for sending it, or 'Save' in order to
store it as a draft into your 'drafts' folder or any user-defined
folder. [<font color="#ff0000">not yet implemented</font>]</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">Hitting
&#8220;Send&#8221; will place your e-mail into the Outbox folder and you can
go on using I2P-Bote, e.g. writing another e-mail, or simply do other
things. I2P-Bote is now sending your e-mail. Once it is sent, it's
automatically removed from Outbox and stored into your Sent folder.
This means, your mail is entirely on the way to its destination
(unless you have set a delay time, which is disabled by default).</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">In
I2P-Bote e-mails are automatically signed (unless send without any
sender identity).<br>
You can
also send e-mails without specifying <i>any </i><span style="font-style: normal;">sender
identity/destination/address, just select &#8220;Anonymous&#8221; in the
scroll-down menu &#8220;From:&#8221;.</span></font></p>
<p style="line-height: 150%;"><br><font face="Arial, sans-serif">In the
default settings I2P-Bote will automatically check for new mails, and
all you need to do in order to see if you got e-mails is look into
your Inbox (link 'Inbox' on the left).<br>
You can
force a manual check by clicking the 'Check Mail' button. This is a
global checking, that tries to fetch new mails for all of your
identities, except for those you have excluded from global checking.
[<font color="#ff0000">not yet implemented</font>]</font></p>
<p style="line-height: 150%;"><br><font face="Arial, sans-serif">The
number of unread e-mails is shown in parenthesis next to the folder's
name in the sidebar. </font>
</p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">Click on
&#8220;<span style="font-style: normal;">Inbox&#8221;</span> to have a list of
received e-mails displayed. You will see two columns with x's or
green checks. Those show you if a mail contains a valid signature and
is thus authentic (Sig) and if the sender's e-mail destination key is
locally known, i.e. in your addressbook (Know). Hence, two green
checks next to a mail entry mean that you already know that e-mail
identity and that the mail is signed by that identity. </font>
</p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">If you
have a certain name in your address book and you get a mail from an
identity with that name, yet Know is <i><u>not</u></i><i> </i><span style="font-style: normal;">displaying
a green check, then it is a </span><i><u>different</u></i><span style="font-style: normal;">
destination that sent and signed this mail; he simply has chosen the
same name you have chosen for one of your contacts.</span></font></p>
<p style="font-style: normal; line-height: 150%;"><font face="Arial, sans-serif">Is
there a green check mark for &#8220;Sig&#8221;, then the mail is correctly
signed by the sender and you may add it to your addressbook under a
different name, which now will be displayed as the sender.</font></p>
<p style="font-style: normal; line-height: 150%;"><font face="Arial, sans-serif">Of
course, a mail without sender destination (&#8220;Anonymous&#8221; is
displayed as sender) will have two x's.</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">Clicking
one of the e-mails displayed in your inbox will open the mail. </font>
</p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">The same
applies to all other folders.</font></p>
<p style="line-height: 150%;"><br><font face="Arial, sans-serif">(Due to
the distributed nature of I2P-Bote, sending as well as checking for
and retrieving e-mails takes a few minutes. With mail routes
activated respectively more. But you need not keep the browser open
for that, simply leave I2P-Bote running as a background process &#8211;
this is also benefits your anonymity)</font></p>
<p style="line-height: 150%;"><br>
</p>
<p style="line-height: 150%;"><br><font face="Arial, sans-serif"><u>2.2.3
Local Address Book</u></font></p>
<p style="line-height: 150%;"><br><font face="Arial, sans-serif">If you
have the I2P-Bote e-mail key from somebody you want to write to more
frequently, it is handy to store that key locally into your address
book (link on the left), specify a name of your own choosing for this
contact and paste his mail destination in the corresponding line,
<font color="#000000">then save.</font></font></p>
<p style="line-height: 150%;"><font color="#000000"><font face="Arial, sans-serif">You
should normally save destinations to your addressbook, so that next
time you get a mail from the same sender it will be shown to be from
the same, locally known sender (&#8220;Loc&#8221; is checked) and a mail sent
by someone else who is just using the same user name will be marked
as NOT known locally (an x in web-UI's 'Know' column or [UNK] before
the sender address in POP3), so you know it's a new/different one. </font></font>
</p>
<p style="line-height: 150%;"><br><br>
<font face="Arial, sans-serif"><u>2.2.4
Settings (and what they mean)</u></font></p>
<p style="line-height: 150%;"><br><font face="Arial, sans-serif">Under
settings you can choose the I2P-Bote interface's <i>language</i>
(currently English or German) and decide whether even with a
non-English language setting everything that will be automatically
added to an e-mail when replying will nonetheless stay in English, so
that the recipient does not know your I2P-Bote is set to a different
language.<br>Otherwise the recipient could guess about your
nationality which would decrease your anonymity. </font>
</p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">Here you
can also adjust the interval for <i>automatic checking</i> of e-mails
and decide whether or not to send any <i>time stamp</i> with your
mails, indicating date and time when the mail was sent. The time
stamps are always in UTC.</font></p>
<p style="font-style: normal; line-height: 150%;"><font face="Arial, sans-serif">(When
using mail routes, the timestamps are automatically disabled.) [<font color="#ff0000">not
yet implemented</font>]</font></p>
<p style="font-style: normal; line-height: 150%;"><br>
</p>
<p style="line-height: 150%;"><font face="Arial, sans-serif"><i>automatic
checking for e-mails:</i></font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">For more
comfort there is the &#8220;Check for mail every XX minutes&#8220; option. </font>
</p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">Here you
can specify how often your I2P-Bote app should try to fetch unread
mails for your identities. This can be set on a per-identity basis
[<font color="#ff0000">not yet implemented</font>]</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">If you
specify a random offset, then it will not check _exactly_ every XX
minutes, but rather every (XX+-offset*XX)minutes, i.e. after a
randomly chosen time between (1-offset)XX minutes and (1+offset)XX
minutes. [<font color="#ff0000">not yet implemented</font>]</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">You can
also totally disable the automatic checking for a given identity.</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">(If you
are not sure about these settings, the defaults should be ok for
you.)</font></p>
<p style="line-height: 150%;"><br><br>
<font face="Arial, sans-serif"><i>Mail
routes</i> are chains of I2P-Bote nodes acting as relays/routers for
other peers and obeying to per-hop delays, thus providing the
high-latency transport for increased anonymity. </font>
</p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">You can
specify the number of nodes (here called hops) that should be chained
to form a mail route. Then each of the e-mail packets sent by the
identity that has mail routes enabled will go through a mail route of
n hops before being stored. You can set a delay for each hop
individually, as no hop should know the time a packet will wait at
the next hop, making the timing unpredictable. [<font color="#ff0000">individual
per-hop and per-identity setting of delays not yet implemented</font>]</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">As delay
you can specify a time frame (e.g. 60-600 minutes) &#8211; then a random
wait time between the two values will be chosen for the packet at
that hop &#8211; or a fix time, then the packet will be forwarded at that
fix time, e. g. noon UTC, no matter when it arrived. [<font color="#ff0000">fix
time not yet implemented</font>] </font>
</p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">(When
using mail routes, the timestamps are automatically disabled. [<font color="#ff0000">not
yet implemented</font>])</font></p>
<p style="line-height: 150%;"><br><font face="Arial, sans-serif">Under
&#8220;<i>mínimo en el bote</i>&#8221; (minimum threshold number of relay packets that
will be sent) you can specify a threshold. As your node can only act
reliably as a mix, if there are enough foreign packets to mix and to
blend own packets with, it will accumulate messages who's delay time
is over until reaching this lower limit. Only when it is surpassed,
your node starts sending them out in random order. [<font color="#ff0000">Not
yet implemented</font>]</font><br><br>
</p>
<p style="line-height: 150%;"><font face="Arial, sans-serif"><i>exclude
identity from global checking</i> [<font color="#ff0000">Not yet
implemented</font>]</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">If you
enable this option for one of your identities, then this one will not
be affected by the global manual checking for mails nor by any global
automatic mail checking.</font></p>
<p style="line-height: 150%;"><br><br>
</p>
<p style="line-height: 150%;"><font face="Arial, sans-serif"><u>2.2.5
E-mails to and from the Internet</u><span style="text-decoration: none;">
[</span><font color="#ff0000"><span style="text-decoration: none;">NOT
YET FULLY IMPLEMENTED!</span></font><span style="text-decoration: none;">]</span></font></p>
<p style="line-height: 150%;"><br><font face="Arial, sans-serif">In order
to be able to send bote mails to the internet and to receive e-mails
from the internet with your I2P-Bote application, you must first
register with an appropriate mail gateway. Currently there is only
one: postman. </font>
</p>
<p style="line-height: 150%;"><br><font face="Arial, sans-serif">1) First, go to:
<a href="http://hq.postman.i2p/?page_id=16">http://hq.postman.i2p/?page_id=16</a> and
register an account. If you already have an account or if you have
just created one as described, proceed with #2.</font></p>
<p style="line-height: 150%;"><br><font face="Arial, sans-serif">2) For an
existing account you can add your I2P-Bote mail destination, so that
e-mails coming from the internet are forwarded to your I2P-Bote app.
To do so go to: <a href="http://hq.postman.i2p/?page_id=74">http://hq.postman.i2p/?page_id=74</a>
and provide the requested information.</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">Now all
e-mails sent to that address (<a href="mailto:name@i2pmail.org">name@i2pmail.org</a>
from the outer internet or <a href="mailto:name@mail.i2p">name@mail.i2p</a>
for mails from other postman subscribers) will be forwarded via the
I2P-Bote network to your I2P-Bote app.</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">(N.B.
When using the <a href="mailto:name@mail.i2p">name@mail.i2p</a> or
<a href="mailto:name@i2pmail.org">name@i2pmail.org</a> addresses
instead of the long addresses, e-mails are no longer end-to-end
encrypted. Therefore, it is recommended to exchange the I2P-Bote mail
destination keys for communicating within the network. Postman has
offered high quality services in I2P for quite a while already, but
be aware that it's a centralized point that might go offline one day,
or worse be taken over by an evildoer that will manipulate mails. As
for network-internal e-mail communication, I2P-Bote makes sure that
if you use the address keys, nobody can tamper with the mails you
send or receive.)</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">If you
want not only to receive e-mails from the internet, but also enable
sending e-mails from I2P-Bote to the internet, you must provide your
I2P-Bote client with the gateway's mail destination key, so that your
I2P-Bote knows where to send those mails to.<br>
You can
do this under &#8220;settings&#8221;. </font><font face="Arial, sans-serif">This
gateway will allow I2P-Bote users to communicate with the standard
e-mail users on the internet as well as with users of postman's
classical i2pmail service (@mail.i2p).</font><br>
<font face="Arial, sans-serif"><br>
In order
to fight abuse, there will be a limitation of the number of e-mails
you can send out to the internet; just like for normal postman mail
service users: If an I2P-Bote user exceeds the quota with outgoing
e-mails, the additional e-mails will be sent back as bounce.</font></p>
<p style="line-height: 150%;"><br><br>
<br>
</p>
<p style="line-height: 150%;"><font face="Arial, sans-serif"><b>3.
Considerations about Anonymity</b></font></p>
<p style="line-height: 150%;"><br>
<font face="Arial, sans-serif">Don't
send identifying information about you (name, address, geographic
location, time zone, age, websites you have just visited or blogged
about, user names, ip numbers, I2P router id, I2P-Bote id, social
security number, credit card number, &#8230;, copies of your passport,
driver's license, home rental contract, photos &#8211; nude or with
clothes &#8211;, documents that contain your username in author's
settings, and many many more)!</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif"><br>
If
possible, </font>
</p>
<ul><li><p style="line-height: 150%;"><font face="Arial, sans-serif">leave
I2P-Bote running 24/7,</font></p>
</li><li><p style="line-height: 150%;"><font face="Arial, sans-serif">use
mailroutes with randomized per-hop delays and/or per-hop fixed send
times, [<font color="#ff0000">not yet </font><font color="#ff0000"><i>fully</i></font><font color="#ff0000">
implemented</font>]</font></p>
</li><li><p style="line-height: 150%;"><font face="Arial, sans-serif">use
a long check interval,</font></p>
</li><li><p style="line-height: 150%;"><font face="Arial, sans-serif">use
a long local delay for own packets,</font></p>
</li><li><p style="line-height: 150%;"><font face="Arial, sans-serif">use
a big check interval randomization. [<font color="#ff0000">not yet
implemented</font>]</font></p>
</li></ul>
<p style="line-height: 150%;"><br><font face="Arial, sans-serif">You can
suppress the sending of date and time in the e-mails' header.</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">When you
reply to an e-mail, certain markers, such as &#8220;Re: [subject of the
mail you're replying to]&#8221; or &#8220;[username] wrote:&#8221;. Those are
different for the languages you can chose from in your language
settings. However, if you don't want the recipient to know what
language you have set, you can suppress translation of these markers,
so that they will be in English, no matter what you language setting
is. In order to do so, mark &#8220;Use English for text added to outgoing
email ('Re:', 'wrote:', etc.) &#8220;</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">Be
careful with the contents you send! Don't include personal
information or information that only you can possess. Don't write I'm
going to bed now, it's late when including time stamps.<br>
The
language in which your write your e-mails, your style and
formulations can also be of interest for an attacker.</font></p>
<p style="line-height: 150%;"><br><font face="Arial, sans-serif">I2P-Bote
also offers the possibility to use different e-mail
identities.<br>Suppose one of you contacts learns about your
identity, as you forgot to erase identifying information in a secret
document you have sent to him. Now if this e-mail's recipient was to
collaborate with others you are in contact with, he could tell them
the real world identity belonging to the Bote address he knows from
you. Thusly, if you communicate with those others using the same Bote
address, they will know who you are.<br>Not so, if you used a
different address for sending mails to them.</font></p>
<p style="line-height: 150%;"><br><br>
<font face="Arial, sans-serif"><b>4.
Technical Concept</b></font></p>
<p style="line-height: 150%;"><br>
<font face="Arial, sans-serif">I2P-Bote
is an end-to-end encrypted, network-internal, fully decentralized
(i.e. serverless) e-mail system. It supports different identities and
does not expose e-mail headers. Currently, it is still alpha software
and can only by accessed via web console. It soon will have POP3
support, and it is planned to guarantee additional anonymity by
providing a high-latency transport option. All bote-mails are
automatically end-to-end encrypted, so that there's no need to set up
extra e-mail encryption (though you can do that), and bote-mails will
be authenticated automatically. As it is decentralized, there is no
e-mail server that could link different e-mail identities as
communicating with each other (<i>profiling</i>): Even the nodes
relaying the mails will not know the sender and apart from sender and
receiver, only the end of the high-latency mail tunnel and the
storing nodes will know to whom (anonymous identity) the mail is
destined. The original sender can have gone offline, long before the
mail becomes available on the other side. This adds on the degree of
anonymity that can be reached with I2P-Bote. For those who do not
want high delays: All these settings are be user-adjustable, so each
user decides on how much anonymity he wants.</font></p><font face="Arial, sans-serif"><font color="#000000"><br>I2P-Bote
nodes store encrypted e-mails into a Kademlia DHT. Therefore, an
e-mail can be sent through a number of other
nodes (relays) for increased security, or directly to<font face="Arial, sans-serif"><font color="#000000"> a
set of storage nodes for faster delivery. The same applies to
retrieving email.<br>(When using mail routes, timestamps are
automatically disabled.)<br></font>[Retrieving via relays not yet
implemented]</font></font></font>
<p><br>
</p>
<p style="line-height: 150%;"><font color="#000000"><font face="Arial, sans-serif">All
nodes are created equal: There are no "supernodes" or
designated relay/storage nodes. Everybody acts as a potential relay
and storage node. The maximum amount of disk space used for
relayed/stored email packets can be configured by the user.</font></font></p>
<p style="line-height: 150%;"><font color="#000000"><font face="Arial, sans-serif">Before
an email is sent to a relay, it is broken up into packets and
encrypted with the recipient's public key. These packets are stored
redundantly in a distributed hash table (DHT).</font></font></p>
<p style="line-height: 150%;"><font color="#000000"><font face="Arial, sans-serif">They
are kept for at least 100 days, during which the recipient can
download them.</font></font></p>
<p style="line-height: 150%;"><font color="#000000"><font face="Arial, sans-serif">Relay
packets also expire after 100 days or more.</font></font></p>
<p style="line-height: 150%;"><font color="#000000"><font face="Arial, sans-serif">If
a node runs out of email storage space, and there are no old packets
that can be deleted, the node refuses storage requests.</font></font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">Furthermore,
I2P-Bote sanitizes the mail headers and does not allow any unneeded
information to be transmitted, thus allowing the use of e-mail
clients without prior checks of what this client sends in the mail
headers. [<font color="#ff0000">POP3 not yet implemented</font>]</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">All the
encryption, path choosing and profiling is done locally so that there
is no trusted party involved.</font></p>
<p style="font-weight: normal; line-height: 150%;"><font face="Arial, sans-serif">Using
I2P-Bote appropriately, that means keeping in mind the considerations
given above and showing some common sense, nobody will be able to
find out who or where you are. And if you are already being observed
and your internet connection sniffed, the observer will not be able
to find out what you send or receive or to whom you are sending to or
receiving from or where your contacts are located.</font></p>
<p style="line-height: 150%;"><br></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif"><br>
Let's go
a bit more into detail:</font></p>
<p style="line-height: 150%;"><br>
</p>
<p style="line-height: 150%;"><font face="Arial, sans-serif"><u>What
I2P-Bote <i>does hide</i>:</u></font></p>
<p style="line-height: 150%;"><br><font face="Arial, sans-serif"><i>I2P-Bote
hides</i> both, the identity and location of sender and receiver, as
well as those of intermediary nodes (relays and storing nodes), the
content of your mails, their size, the number of mails you send.</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">Only the
recipient can know the sender's bote mail destination, and if he
choses not to send his destination, not even the recipient will know
it.</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">Even if
you send time stamps, your time zone will not be disclosed.</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">Furthermore,
I2P-Bote hides ...</font></p>
<p style="line-height: 150%;">&nbsp;&nbsp;&nbsp; <font face="Arial, sans-serif">- the
fact that you run I2P-Bote</font></p>
<p style="line-height: 150%;">&nbsp;&nbsp;&nbsp; <font face="Arial, sans-serif">- the
fact that you send a mail</font></p>
<p style="line-height: 150%;">&nbsp;&nbsp;&nbsp; <font face="Arial, sans-serif">- the
fact that you receive a mail</font></p>
<p style="line-height: 150%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face="Arial, sans-serif">and
hence</font></p>
<p style="line-height: 150%;">&nbsp;&nbsp;&nbsp; <font face="Arial, sans-serif">- the
time you send a mail</font></p>
<p style="line-height: 150%;">&nbsp;&nbsp;&nbsp; <font face="Arial, sans-serif">- the
time you receive a mail</font></p>
<p style="line-height: 150%;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font face="Arial, sans-serif">and</font></p>
<p style="line-height: 150%;">&nbsp;&nbsp;&nbsp; <font face="Arial, sans-serif">- the
upper limit of number of mails an unknown user receives, - nota bene:
an abstract <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; user, no concrete one, just concluding its
existence from the existence of the mail identity<br>&nbsp;&nbsp;&nbsp; - as he
could always have more than one e-mail identity; and the lower limit
as an <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; identity also sends out test and dummy messages</font></p>
<p style="line-height: 150%;"><br><br>
</p>
<p style="line-height: 150%;"><font face="Arial, sans-serif"><u>What
I2P-Bote <i>hides partially</i>: </u></font>
</p>
<p style="line-height: 150%;"><br><font face="Arial, sans-serif">The
I2P-Bote address of the recipient will only be known to sender and
recipient(s). </font>
</p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">In case
of multiple recipients, each one will see all other recipients that
the mail was addressed to via &#8220;To:&#8221; or &#8220;CC:&#8221;. </font>
</p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">All
entries that were under &#8220;BCC:&#8221; will only be visible to the sender
and this very recipient. </font>
</p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">The time
an sent time will, if at all, only be visible to sender and
recipient.</font></p>
<p style="line-height: 150%;"><br><br>
<font face="Arial, sans-serif"><u>What
I2P-Bote <i>can hide</i> optionally: </u></font>
</p>
<p style="line-height: 150%;"><br><br>
<font face="Arial, sans-serif">- If
mail routes are use, the time a bote mail is sent</font></p>
<p style="line-height: 150%;"> <font face="Arial, sans-serif">- If
mail routes are used, the time a bote mail is fetched. [<font color="#ff0000">not
yet implemented</font>]</font></p>
<p style="line-height: 150%;"> <font face="Arial, sans-serif">- If the
sender suppresses timestamps only the sender himself will know when
he sent a<br> mail.</font></p>
<p style="line-height: 150%;"><br><br>
<font face="Arial, sans-serif"><u>What
I2P-Bote <i>cannot hide</i>: </u></font>
</p>
<p style="line-height: 150%;"><font face="Arial, sans-serif"><br>
I2P-Bote
cannot hide the frequency a given identity checks for new mails nor
the number of mails a given identity receives.</font></p>
<p style="line-height: 150%;"><br><br>
</p>
<p style="line-height: 150%;"><font face="Arial, sans-serif"><br>
Not even
for bootstrapping I2P-Bote depends on a central node, as it uses
Seedless.<br>
</font></p>
<p style="line-height: 150%;"><br><br>
<br>
</p>
<p style="line-height: 150%;"><font face="Arial, sans-serif"><b>5
Terminology/Glossary of Terms:</b></font></p>
<p style="line-height: 150%;"><br>
</p>
<p style="line-height: 150%;"><font face="Arial, sans-serif"><i><u>I2P-Bote
(router/node) id</u>:</i></font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">This is
the id an I2P-Bote router is known as. It is used for contacting this
router, for storing, relaying and fetching mails, but also used in
the hop-to-hop encryption and for simply contacting it via I2P, as it
is at the same the I2P-Bote router's I2P tunnel destination. It is
displayed to represent an I2P-Bote node in the stats.</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">So the
router id corresponds to the I2P destination (the address of an
I2P-Bote node on the I2P network - there is no need to know it unless
you are having problems connecting to other I2P-Bote nodes.)</font></p>
<p style="font-weight: normal; line-height: 150%;"><br><font face="Arial, sans-serif"><i><u>I2P-Bote
e-mail destination:</u></i></font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">The
I2P-Bote e-mail destination (key) is an identifier by which somebody
can be reached via I2P-Bote, so as the name states: an e-mail
destination. Thus it is for I2P-Bote what an e-mail address is for
standard e-mail system: The e-mail destination is the actual address
for sending e-mails, for storing them into and for fetching them from
the DHT. <br>At the same time it used for the end-to-end encryption
of e-mails, header information and attachments. </font>
</p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">An
I2P-Bote e-mail destination is a Base64 string containing a public
encryption key and a signature verification key. Example:</font></p>
<p style="line-height: 150%;">
</p>
<p style="line-height: 150%;">
<font face="Arial, sans-serif">uQtdwFHqbWHGyxZN8wChjWbCcgWrKuoBRNoziEpE8XDt8koHdJiskYXeUyq7JmpG</font></p>
<p style="line-height: 150%;">
<font face="Arial, sans-serif">In8WKXY5LNue~62IXeZ-ppUYDdqi5V~9BZrcbpvgb5tjuu3ZRtHq9Vn6T9hOO1fa</font></p>
<p style="line-height: 150%;">
<font face="Arial, sans-serif">FYZbK-FqHRiKm~lewFjSmfbBf1e6Fb~FLwQqUBTMtKYrRdO1d3xVIm2XXK83k1Da</font></p>
<p style="line-height: 150%;">
<font face="Arial, sans-serif">-nufGASLaHJfsEkwMMDngg8uqRQmoj0THJb6vRfXzRw4qR5a0nj6dodeBfl2NgL9</font></p>
<p style="line-height: 150%;">
<font face="Arial, sans-serif">HfOLInwrD67haJqjFJ8r~vVyOxRDJYFE8~f9b7k3N0YeyUK4RJSoiPXtTBLQ2RFQ</font></p>
<p style="line-height: 150%;">
<font face="Arial, sans-serif">gOaKg4CuKHE0KCigBRU-Fhhc4weUzyU-g~rbTc2SWPlfvZ6n0voSvhvkZI9V52X3</font></p>
<p style="line-height: 150%;">
<font face="Arial, sans-serif">SptDXk3fAEcwnC7lZzza6RNHurSMDMyOTmppAVz6BD8PB4o4RuWq7MQcnF9znElp</font></p>
<p style="line-height: 150%;">
<font face="Arial, sans-serif">HX3Q10QdV3omVZJDNPxo-Wf~CpEd88C9ga4pS~QGIHSWtMPLFazeGeSHCnPzIRYD</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif"><br>I2P-Bote
router/node id and I2P-Bote e-mail destinations look similar, but are
completely independent of each other.</font></p>
<p style="line-height: 150%;"><br><font face="Arial, sans-serif"><i><u>E-mail
address:</u></i></font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">E-mail
addresses in I2P-Bote are shortcuts for e-mail destinations.</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">The
e-mail address &lt;--&gt; e-mail destination mappings are stored in
two places: the local address book and the distributed address
directory [<font color="#ff0000">the latter not yet implemented</font>].</font></p>
<p style="line-height: 150%;"><br><font face="Arial, sans-serif"><i><u>I2P-Bote
e-mail identity:</u></i></font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">The
I2P-Bote e-mail identity is a set of an I2P-Bote e-mail destination
key, the corresponding private keys and a name given to it by the
user. This name will be sent with the destination key if you do not
suppress sending information about the sender.</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">However
it will only be displayed for the recipient in case he does not have
a name for this destination in his local address book.</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">So
technically speaking, an e-mail identity consists of four things:</font></p>
<p style="line-height: 150%;"> <font face="Arial, sans-serif">* an
e-mail destination (i.e. two public keys)</font></p>
<p style="line-height: 150%;"> <font face="Arial, sans-serif">* two
private keys for the e-mail destination</font></p>
<p style="line-height: 150%;"> <font face="Arial, sans-serif">* a
public name which can be shown to other people in e-mails</font></p>
<p style="line-height: 150%;"> <font face="Arial, sans-serif">* a
description which is not shown to anybody but you.</font></p>
<p style="line-height: 150%;"> <font face="Arial, sans-serif">(It
helps you remember which e-mail identity you use for which purpose.)</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">An e-mail
identity is not required for sending emails (although then only
"Anonymous" can be selected for the "sender"
field).</font></p>
<p style="line-height: 150%;"><br></p><p style="line-height: 150%;"><font face="Arial, sans-serif"><span style="text-decoration: underline; font-style: italic;">Mail
routes</span>:</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">Mail
routes are an additional high-latency transport for I2P-Bote. For
this, a chain of I2P-Bote nodes is built, acting as relays/routers
for packets and obeying to individual per-hop delays; [<font color="#ff0000">still
no individual setting for delays implemented</font>]</font></p>
<p style="line-height: 150%; font-weight: bold;"><font face="Arial, sans-serif"><br>
BEWARE!</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">If you
choose this option - especially with many hops and / or long delay
times, don't be surprised if your mail does not reach its destination
too soon. It will, of course, take longer &#8211; up to several days!</font><br>
</p>
<p style="line-height: 150%;"><br>
<br>
</p>
<p style="line-height: 150%; font-weight: bold; font-style: italic;"><font face="Arial, sans-serif">6.&nbsp; Credits</font></p>
<p style="line-height: 150%;">
</p><p style="line-height: 150%;"><font face="Arial, sans-serif">Idea &amp;
technical concept: HungryHobo, Mixxy</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">Implementation:
HungryHobo</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">Plugin
support: zzz, HungryHobo</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">User
interface: HungryHobo</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">Seedless
integration: sponge</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">German
translation: HungryHobo</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">French
translation: albat, Redzara, Mixxy</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">Spanish
translation: Mixxy</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">Alpha
testing: HungryHobo, Mixxy, Returning Novice, sponge, and many others</font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif"><b><br>
<br>
</b></font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif"><b>7.
Technical Details</b></font></p>
<p style="line-height: 150%;"><font face="Arial, sans-serif">-- see
techdoc.txt --</font></p>
<p style="line-height: 150%;"><br><br>
</p>
<p style="line-height: 150%;"><br><br>
</p>
<p style="line-height: 150%; font-weight: bold; font-style: italic;"><font face="Arial, sans-serif">ENJOY THE
BOTE FEELING!!</font></p>
</body></html>

View File

@ -1,862 +0,0 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
<TITLE>Guide de l'utilisateur</TITLE>
<META NAME="GENERATOR" CONTENT="LibreOffice 3.3 (Linux)">
<META NAME="CREATED" CONTENT="0;0">
<META NAME="CHANGED" CONTENT="20110407;10200100">
<STYLE TYPE="text/css">
<!--
@page { margin: 2cm }
P { margin-bottom: 0.21cm }
A:link { so-language: zxx }
-->
</STYLE>
</HEAD>
<BODY LANG="fr-FR" DIR="LTR">
<P ALIGN=CENTER STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif"><B>Guide
de l'utilisateur I2P-Bote</B></FONT></P>
<P STYLE="line-height: 150%"><BR><BR>
</P>
<P STYLE="line-height: 150%"><BR><BR>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif"><B>1.
Introduction</B></FONT></P>
<P STYLE="line-height: 150%"><BR><BR><FONT FACE="Arial, sans-serif">I2P-Bote
est une application de messagerie sécurisée pour I2P, à anonymat
élevé et simple à utiliser. C'est un système sans serveur,
entièrement décentralisé, qui constitue et génère un réseau
pairs à pairs sur le réseau d'anonymisation I2P, lui-même conçu
selon les règles de l'art ; l'adjonction optionnelle d'un transport
à la façon de Mixminion le débarrasse des faiblesses intrinsèques
des réseaux à basse latence.</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">I2P-Bote
tire donc le meilleur de l'anonymat fourni par I2P, à quoi il
apporte son propre niveau supplémentaire d'anonymat par l'ajout
d'une autre couche d'anonymisation (sur-réseau).</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Ce
concept d'anonymat étagé est ce rend I2P-Bote si souple :</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Vous
pouvez le configurer pour être extrêmement anonyme et lent, ou
moins anonyme mais plus rapide et efficace. Dans tous les cas,
I2P-Bote<FONT COLOR="#000000"> procure toujours un très bon anonymat
à l'expéditeur et au destinataire, ainsi qu'un cryptage de bout en
bout*. </FONT></FONT>
</P>
<P STYLE="line-height: 150%"><FONT COLOR="#000000"><FONT FACE="Arial, sans-serif">I2P-Bote
permet de rendre vos communications encore plus anonymes, en activant
les routes à haute latence au prix d'une baisse de performance,
cependant. Les utilisateurs qui souhaitent que leurs messages
arrivent au plus vite peuvent désactiver les routes de messages et
utiliser l'envoi «&nbsp;direct&nbsp;» sur I2P. Ils sont ainsi
assurés de bénéficier au minimum de l'anonymat d'origine des
connexions I2P. </FONT></FONT>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif"><FONT COLOR="#000000">Pour
atteindre une ergonomie élevée, nous l'avons conçu pour qu'il
puisse fonctionner avec les logiciels clients de messagerie standards
tels que Thunderbird, Evolution ou Kmail, sans avoir à se préoccuper
des informations supplémentaires que ces applications envoient dans
leurs en-têtes [</FONT><FONT COLOR="#ff0000">PAS ENCORE IMPLÉMENTÉ</FONT><FONT COLOR="#000000">].
De plus, il y a une interface web qui vous permet d'envoyer et de
recevoir des messages, et de gérer vos préférences et vos
identités.</FONT></FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">I2P-Bote
est facile à utiliser : si vous n'utilisez pas déjà I2P, installez
le depuis <A HREF="http://www.i2p2.de/">http://www.i2p2.de</A> puis
installez le greffon I2P-Bote comme expliqué dans ce manuel. Sinon,
continuez la lecture!**</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif"><I>La
version actuelle est la 0.2.6.</I></FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">*Sauf si
vous recevez ou envoyez des messages de/vers l'Internet classique,
TOUS les messages le corps, les pièces jointes et les en-têtes
à part l'adresse du destinataire (objet, date et heure,
expéditeur,...) sont automatiquement cryptés de bout en bout de
façon transparente. L'adresse du destinataire n'est visible que par
le dernier nœud de la route qui stocke les paquets dans le réseau
kad, ainsi que par les nœuds de stockage, mais ils ne peuvent pas
lire les messages, ni qui l'a envoyé, ni qui le relèvera.</FONT></P>
<P STYLE="line-height: 150%"><BR><BR>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">**Bien
sûr, vous pouvez aussi le compiler à partir des sources.</FONT></P>
<P STYLE="line-height: 150%"><BR><BR>
</P>
<P STYLE="line-height: 150%"><BR><BR>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif"><B>2.
Procédures</B></FONT></P>
<P STYLE="line-height: 150%"><BR><BR>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif"><U>2.1.
Installation</U></FONT></P>
<P STYLE="line-height: 150%"><BR><BR>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Pour
installer I2P-Bote, rendez-vous en bas de la page de configuration du
client I2P sur </FONT>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif"><A HREF="http://localhost:7657/configclients.jsp">http://localhost:7657/configclients.jsp</A>
</FONT>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">en entrez
:</FONT></P>
<P STYLE="line-height: 150%"><A HREF="http://tjgidoycrw6s3guetge3kvrvynppqjmvqsosmtbmgqasa6vmsf6a.b32.i2p/i2pbote.xpi2p"><FONT FACE="Arial, sans-serif">http://tjgidoycrw6s3guetge3kvrvynppqjmvqsosmtbmgqasa6vmsf6a.b32.i2p/i2pbote.xpi2p</FONT></A></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">(<A HREF="http://i2pbote.i2p/i2pbote.xpi2p">http://i2pbote.i2p/i2pbote.xpi2p</A>
marche aussi, si vous avez i2pbote.i2p dans votre carnet d'adresses
ou un abonnement)</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">dans le
champ «&nbsp;…, URL de téléchargement&nbsp;:&nbsp;», puis
cliquez sur le bouton «&nbsp;Installer le greffon&nbsp;». Attendez
jusque à ce que le panneau de surveillance sur la gauche indique que
le greffon est installé et démarré. </FONT>
</P>
<P STYLE="line-height: 150%"><BR><BR>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Pour
mettre à jour I2P-Bote, dans la même page, cliquez sur «&nbsp;Mise
à jour&nbsp;»dans le cadre dédié au greffon une fois celui-ci
installé.</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif"><U>2.2.
Utiliser I2P-Bote</U></FONT></P>
<P STYLE="line-height: 150%"><BR><FONT FACE="Arial, sans-serif">Dans
la console du routeur <A HREF="http://127.0.0.1:7657/">http://127.0.0.1:7657/</A>
cliquez sur </FONT><FONT FACE="Arial, sans-serif"><I>SecureMail</I></FONT>
<FONT FACE="Arial, sans-serif">en haut à gauche dans le panneau de
surveillance. Vous êtes maintenant dans l'interface web d'I2P-Bote.</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Après
son lancement, I2P-Bote a besoin d'un peu plus de trois minutes pour
être entièrement opérationnel (Il est configuré pour démarrer
automatiquement en même temps que le routeur). </FONT>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Donc,
quand le panneau de surveillance indique «&nbsp;Réseau&nbsp;: OK&nbsp;»,
c'est prêt..</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Si vous
utiliser I2P-Bote pour vous-même, il vous faut créer une identité.</FONT>
</P>
<P STYLE="line-height: 150%"><BR><BR>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif"><U>2.2.1
Création d'une identité</U></FONT></P>
<P STYLE="line-height: 150%"><BR><FONT FACE="Arial, sans-serif">Cliquez
sur «&nbsp;Identités&nbsp;» sur la gauche, puis sur le bouton
«&nbsp;Nouvelle identité&nbsp;».</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Entrez au
moins un «&nbsp;Nom public&nbsp;» et cliquez sur «&nbsp;Créer&nbsp;».
C'est tout ce qu'il faut faire pour créer une identité.</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Le nom
public est le nom que vous voyez pour cette identité (utile quand
vous en avez plusieurs, pour communiquer avec différents groupes
d'utilisateurs ou pour des besoins différents) et il sera envoyé
aux destinataires en tant que «&nbsp;nom d'expéditeur&nbsp;». Il
n'est pas nécessaire qu'il soit unique. </FONT>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">(Comme on
peut choisir ici n'importe quel nom n'importe qui pourrait
choisir ici HungryHobo comme nom public ce champ n'est pas conçu
pour apporter au destinataire la certitude que deux messages
proviennent du même expéditeur. C'est pourquoi c'est le nom
sauvegardé dans le carnet d'adresses local [il ne peut y avoir qu'un
seul nom par clé de destination] qui est affiché dans la boîte de
réception si l'expéditeur en a sélectionné un lors de l'envoi
[envoi non anonyme], et vous verrez alors une marque verte dans la
colonne «&nbsp;Connu&nbsp;» même si le nom public spécifié par
l'expéditeur est différent pour cette sienne identité, indiquant
ainsi qu'il s'agit bien de la destination connue localement. S'il n'y
a pas d'entrée pour une destination donnée dans le carnet
d'adresses, le nom indiqué par l'expéditeur est affiché précédé
du préfixe [UNK] dans les logiciels clients de messagerie) [<FONT COLOR="#ff0000">POP3
N'EST PAS ENCORE IMPLÉMENTÉ</FONT>].</FONT></P>
<P STYLE="line-height: 150%"><BR><FONT FACE="Arial, sans-serif">Vous
pouvez aussi compléter les autres champs, si vous le souhaitez :</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Description
ce champ est conservé localement, pas diffusé. Il ne sert qu'à
vous : si vous voulez ajouter des informations supplémentaires à
votre usage au sujet de cette identité, ce champ est prévu pour
cela. </FONT>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Adresse
e-mail champ pas encore utilisé.</FONT><FONT COLOR="#ff0000"><FONT FACE="Arial, sans-serif"><BR></FONT></FONT><BR><FONT COLOR="#000000"><FONT FACE="Arial, sans-serif">Choisissez
un algorithme de cryptage parmi ceux proposés. Dans le doute, gardez
celui proposé par défaut.</FONT></FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Vous
pouvez cliquer sur une de vos identités et copier la longue clé
affichée sous «&nbsp;Destination de messagerie&nbsp;». C'est votre
adresse e-mail I2P-Bote. Si vous voulez recevoir des messages de
quelqu'un, il faudra la lui transmettre.</FONT><BR><BR><FONT FACE="Arial, sans-serif">Vous
pouvez maintenant envoyer et recevoir des messages I2P-Bote.</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Mais vous
devriez regarder les réglages d'I2P-Bote et vous assurer qu'il sont
conformes à vos besoins.</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">(Vous
pouvez créer plusieurs identités et leur associer des réglages
différents.)</FONT></P>
<P STYLE="line-height: 150%"><BR><BR>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif"><U><BR>2.2.2
Envoyer et recevoir des messages</U></FONT></P>
<P STYLE="line-height: 150%"><BR><BR>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Vous avez
besoin de la clé de destination de message I2P-Bote du correspondant
à qui vous voulez envoyer un message bote. </FONT>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Pour
envoyer un message, cliquez sur «&nbsp;Nouveau&nbsp;», choisissez
votre identité d'expéditeur ou «&nbsp;Anonyme&nbsp;» dans le
champ «&nbsp;De&nbsp;:&nbsp;» et entrez la destination du
destinataire dans le champ «&nbsp;À&nbsp;:&nbsp;», ou une adresse
mail.</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">(Vous
pouvez aussi cliquer sur le bouton «&nbsp;Carnet d'adresses&nbsp;»
tout proche de ce champ, pour choisir une destination stockée
localement dans votre carnet d'adresses&nbsp;: cochez le/les
utilisateur(s) destinataires et cliquez sur le bouton “Ajouter les
destinataires&nbsp;»)</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Vous
pouvez ajouter plusieurs destinataires et changer l'attribut «&nbsp;À&nbsp;:&nbsp;»
pour «&nbsp;Cc:&nbsp;» ou «&nbsp;Cci:&nbsp;».</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Le bouton
«&nbsp;+&nbsp;» ajoute des lignes destinataires supplémentaires.</FONT></P>
<P STYLE="line-height: 150%"><BR><BR>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Rédigez
maintenant votre message bote et cliquez sur «&nbsp;Envoyer&nbsp;»pour...
l'envoyer, ou «&nbsp;Enregistrer&nbsp;» pour le sauvegarder dans
votre dossier «&nbsp;Brouillons&nbsp;» ou tout autre dossier
personnel [<FONT COLOR="#ff0000">pas encore implémenté</FONT>].</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">L'action
d'envoi déplace le message dans le dossier «&nbsp;Boîte d'envoi&nbsp;»
et vous pouvez continuer à utiliser I2P-Bote, par exemple pour
écrire un autre message, gérer votre carnet d'adresses, etc...
I2P-Bote est alors en train d'envoyer votre message. Une fois envoyé,
il est déplacé de la boîte d'envoi vers le dossier «&nbsp;Courriers
envoyés&nbsp;». Votre message est en route (à moins que vous
n'ayez défini un retard, ce qui n'est pas activé pas défaut).</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Dans
I2P-Bote, les messages sont signés automatiquement (sauf ceux que
vous envoyez comme «&nbsp;Anonyme&nbsp;», c'est à dire sans
choisir d'identité d'expéditeur)&nbsp;: en effet, vous pouvez
décider de ne pas choisir d'identité d'expéditeur.</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">De par
les réglages par défaut, I2P-Bote relève le automatiquement
courrier, et tout ce que vous avez à faire pour savoir si vous avez
reçu de nouveaux messages est de regarder dans la boîte de
réception (lien sur la gauche).<BR>Vous pouvez forcer une relève en
cliquant cliquant sur le bouton «&nbsp;Relever le courrier&nbsp;».
C'est une vérification globale qui tente de récupérer les nouveaux
messages destinés à toutes vos identités à l'exception de celles
exclues de cette fonctionnalité [</FONT><FONT COLOR="#ff0000"><FONT FACE="Arial, sans-serif">pas
encore implémenté</FONT></FONT><FONT FACE="Arial, sans-serif">].</FONT></P>
<P STYLE="line-height: 150%"><BR><FONT FACE="Arial, sans-serif">Le
nombre de messages non lus est indiqué entre parenthèses à
proximité du nom du dossier dans le cadre de gauche. </FONT>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Cliquez
sur «&nbsp;Boîte de réception&nbsp;» pour visualiser la liste des
messages reçus. Vous y voyez deux colonnes peuplées de «&nbsp;x&nbsp;»
et de coches vertes. Elles vous indiquent si le message en question
contient un signature valide et qu'il est donc certifié comme
authentique et intègre (Sig), et si la destination de l'expéditeur
est déjà connue, c'est à dire déjà enregistrée dans votre
carnet d'adresses (Connu). Donc, deux coches vertes pour un message
signalent que vous connaissez son expéditeur et que le message a été
signalé par lui. </FONT>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Si vous
avez dans votre carnet d'adresses un certain nom et que vous recevez
un message de la part d'une identité affichant ce nom, alors si la
colonne «&nbsp;Connu&nbsp;» <U>n'indique pas</U> une <SPAN STYLE="font-style: normal">coche
verte, c'est que le message provient d'une destination </SPAN><SPAN STYLE="font-style: normal"><U>différente</U></SPAN>
<SPAN STYLE="font-style: normal">de celle contenue dans votre carnet
d'adresses&nbsp;; son propriétaire a simplement choisi le même nom
que celui d'un de vos contacts déjà enregistré.</SPAN></FONT></P>
<P STYLE="font-style: normal; line-height: 150%"><FONT FACE="Arial, sans-serif">S'il
y a une coche verte dans la colonne «&nbsp;Sig&nbsp;», c'est que le
message est correctement signé et vous pouvez ajouter l'expéditeur
à votre carnet d'adresses sous un nom différent qui sera dès lors
affiché en tant qu'expéditeur.</FONT></P>
<P STYLE="font-style: normal; line-height: 150%"><FONT FACE="Arial, sans-serif">Évidemment,
un message sans destination d'expéditeur (“Anonyme” affiché
comme expéditeur) sera repéré par deux marques «&nbsp;x&nbsp;».</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Un clic
sur un des messages de la liste ouvre celui-ci. </FONT>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Ceci vaut
pour tous les autres dossiers.</FONT></P>
<P STYLE="line-height: 150%"><BR><FONT FACE="Arial, sans-serif">(De
par la nature décentralisée d'I2P-Bote, l'envoi comme la relève
prennent quelques minutes. Sensiblement plus lorsque les routes de
messages sont activées. Mais vous n'avez pas besoin de garder le
navigateur ouvert&nbsp;: il suffit de laisser tourner I2P-Bote en
tant que processus d'arrière plan ce dont profite aussi votre
anonymat)</FONT></P>
<P STYLE="line-height: 150%"><BR><BR>
</P>
<P STYLE="line-height: 150%"><BR><FONT FACE="Arial, sans-serif"><U>2.2.3
Carnet d'adresses local</U></FONT></P>
<P STYLE="line-height: 150%"><BR><FONT FACE="Arial, sans-serif">Si
vous avez la clé de destination I2P-Bote de quelqu'un à qui vous
voulez écrire souvent, il est commode de l'enregistrer dans votre
carnet d'adresses local (lien sur la gauche)&nbsp;: choisissez un nom
(de façon complètement arbitraire), collez la clé dans le champ
idoine et sauvegardez.</FONT></P>
<P STYLE="line-height: 150%"><FONT COLOR="#000000"><FONT FACE="Arial, sans-serif">C'est
normalement ce que vous devriez faire, en sorte que le prochain
message de ce destinataire soit marqué comme «&nbsp;Connu&nbsp;»,
alors qu'un message d'un autre expéditeur de même nom serait marqué
d'un «&nbsp;x&nbsp;» (ou préfixé [UNK] dans un client de
messagerie), vous prévenant ainsi qu'il provient de quelqu'un
d'autre. </FONT></FONT>
</P>
<P STYLE="line-height: 150%"><BR><BR><FONT FACE="Arial, sans-serif"><U>2.2.4
Les préférences de réglages (et ce qu'elles signifient)</U></FONT></P>
<P STYLE="line-height: 150%"><BR><FONT FACE="Arial, sans-serif">Dans
les préférences vous pouvez choisir la langue de l'interface
d'I2P-Bote et décider que même si vous choisissez une autre langue,
tout ce qui sera automatiquement ajouté comme titres d'en-têtes
restera cependant en anglais pour ne pas dévoiler votre langue (et
par là même, peut-être en déduire votre nationalité et
compromettre votre anonymat à ce sujet, la FAQ I2P-Bote et le
chapitre 3 de ce manuel donnent d'autres conseils).</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Vous
pouvez aussi régler l'intervalle de relève automatique, et
l'inclusion ou l'exclusion des horodatages pour vos messages (les
horodatages sont toujours en UTC).</FONT></P>
<P STYLE="font-style: normal; line-height: 150%"><FONT FACE="Arial, sans-serif">(Quand
vous utilisez les routes de messages, les horodatages sont
automatiquement désactivés [<FONT COLOR="#ff0000">pas encore
implémenté</FONT>]).</FONT></P>
<P STYLE="line-height: 150%"><BR><BR>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif"><I>Relève
automatique:</I></FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Pour le
confort d'utilisation, cochez «&nbsp;Relever le courrier toutes les
XX minutes&nbsp;:&nbsp;» et saisissez la valeur de l'intervalle. </FONT>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Ceci
définit la fréquence de tentatives de téléchargement de nouveaux
messages pour vos identités. Ça peut être différentié par
identité [<FONT COLOR="#ff0000">pas encore implémenté</FONT>].</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Si vous
définissez un décalage aléatoire, la relève n'aura pas lieu
exactement toutes les XX minutes, mais toutes les
(XX+/-décalage*XX)minutes, c'est à dire après un temps aléatoire
compris entre (1-décalage)*XX minutes et (1+décalage)*XX minutes
[<FONT COLOR="#ff0000">pas encore implémenté</FONT>].</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Vous
pouvez également désactiver complètement la relève automatique
pour une identité donnée.</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">(Si vous
n'êtes pas à l'aise avec ces réglages, les valeurs par défaut
vous conviendront très bien)</FONT></P>
<P STYLE="line-height: 150%"><BR><BR><FONT FACE="Arial, sans-serif">Les
</FONT><FONT FACE="Arial, sans-serif"><I>Routes de messagerie </I></FONT><FONT FACE="Arial, sans-serif">sont
des chînes de nœuds I2P-Bote agissant en tant que routeurs relais
pour le compte d'autres pairs et obéissant à des délais par saut
définis par l'expéditeur, fournissant ainsi le transport à haute
latence garant d'un anonymat plus élevé. </FONT>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Vous
pouvez spécifier le nombre de nœuds (sauts) nécessaires à la
constitution d'une route de messagerie. Ensuite, chacun des paquets
de message envoyés par l'identité qui a activé la fonction routes
de messagerie passera par une route de n sauts avant d'être stocké.
Vous pouvez définir un délai pour chaque saut individuel, pour
qu'aucun saut ne puisse savoir combien de temps le paquet attendra au
niveau du saut suivant, ce qui rend la prédiction horaire impossible
[<FONT COLOR="#ff0000">les définitions des retards par saut et par
identité ne sont pas encore implémentées</FONT>].</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Vous
pouvez définir une tranche de temps (p.e. 60-600 minutes) puis
un retard aléatoire entre ces deux valeurs sera choisi pour le
paquet au niveau de tel saut ou une heure fixe à laquelle le
paquet sera transféré, p.e. cet après-midi UTC, indépendamment du
moment où il est arrivé [<FONT COLOR="#ff0000">heure fixe pas
encore implémentée</FONT>]. </FONT>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">(Quand
vous utilisez les routes de messagerie, les horodatages sont
automatiquement désactivés [<FONT COLOR="#ff0000">pas encore
implémenté</FONT>]).</FONT></P>
<P STYLE="line-height: 150%"><BR><FONT FACE="Arial, sans-serif">Sous
«&nbsp; </FONT><FONT FACE="Arial, sans-serif"><I>Minimum dans la
messagerie</I></FONT>&nbsp;<FONT FACE="Arial, sans-serif">» (nombre
minimum de paquets relayés à envoyer), vous pouvez indiquer un
seuil. Comme votre instance I2P-Bote peut fonctionner comme un relais
mélangeur, s'il y a suffisamment de paquets étrangers à mélanger
et avec lesquels camoufler les vôtres, elle va accumuler les
messages pour lesquels le retard demandé n'est pas échu jusqu'à
atteindre ce seuil. Une fois atteint, votre bote commence à les
transférer aléatoirement [</FONT><FONT COLOR="#ff0000"><FONT FACE="Arial, sans-serif">pas
encore implémenté</FONT></FONT><FONT FACE="Arial, sans-serif">].</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif"><I>Exclure
l'identité de la relève globale</I> [<FONT COLOR="#ff0000">pas
encore implémenté</FONT>].</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Si vous
activez cette option pour une de vos identités, elle ne sera pas
prise en compte ni par la fonction de relève globale automatique
planifiée, ni par la relève manuelle globale.</FONT></P>
<P STYLE="line-height: 150%"><BR><BR>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif"><U>2.2.5
E-mails de et vers l'Internet</U><SPAN STYLE="text-decoration: none">
[</SPAN><FONT COLOR="#ff0000"><SPAN STYLE="text-decoration: none">NOT
YET FULLY IMPLEMENTED!</SPAN></FONT><SPAN STYLE="text-decoration: none">]</SPAN></FONT></P>
<P STYLE="line-height: 150%"><BR><FONT FACE="Arial, sans-serif">Pour
pouvoir envoyer des messages bote vers l'Internet et recevoir des
e-mails venant de l'Internet dans l'application I2P-Bote, vous devez
d'abord vous enregistrer auprès d'une passerelle de messagerie. Il
n'y en a actuellement qu'une seule&nbsp;: postman. </FONT>
</P>
<P STYLE="line-height: 150%"><BR><FONT FACE="Arial, sans-serif">1)
D'abord, allez sur : <A HREF="http://hq.postman.i2p/?page_id=16">http://hq.postman.i2p/?page_id=16</A>
et créez un compte. Si vous en avez déjà un, ou si vous venez de
le créer, passer à l'étape 2).</FONT></P>
<P STYLE="line-height: 150%"><BR><FONT FACE="Arial, sans-serif">2)
Pour un compte donné, vous pouvez ajouter votre clé de destination
de messagerie, pour que les messages arrivant d'Internet puissent
être transférés vers votre application I2P-Bote. Pour ce faire
allez sur : <A HREF="http://hq.postman.i2p/?page_id=74">http://hq.postman.i2p/?page_id=74</A>
et indiquez les informations demandées.</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Maintenant,
tous les e-mails envoyés à cette adresse (<A HREF="mailto:name@i2pmail.org">nom@i2pmail.org</A>
depuis l'Internet externe ou depuis <A HREF="mailto:name@mail.i2p">blaze@mail.i2p</A>
pour les messages d'autres comptes postman) seront transférés par
le réseau I2P-Bote à votre application I2P-Bote.</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">(N.B. En
utilisant les adresses <A HREF="mailto:name@mail.i2p">nom@mail.i2p</A>
ou <A HREF="mailto:name@i2pmail.org">nom@i2pmail.org</A> au lieu des
longues clés de destination, les messages ne sont plus cryptés de
bout en bout. En conséquence, il est recommandé d'échanger les
clés I2P-Bote pour la communication intra réseau. Postman offre des
services de haute qualité sur I2P depuis déjà un bon moment, mais
soyez conscient qu'il s'agit d'un point centralisé qui pourrait un
jour cesser de fonctionner, ou pire, tomber sous le contrôle d'un
nuisible qui pourrait manipuler les courriers. Comme pour la
messagerie intra réseau, I2P-Bote vous assure que si vous utilisez
des clés de destination, personne ne peut bricoler les messages que
vous recevez ou envoyez.)</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Si vous
voulez non seulement recevoir des messages d'Internet, mais aussi
pouvoir en envoyer vers Internet depuis I2P-Bote, vous devez indiquer
à votre application cliente I2P-Bote la clé de destination de la
passerelle de messagerie, pour que votre I2P-Bote sache où envoyer
les messages.<BR>Ceci se fait dans les «&nbsp;Préférences&nbsp;».
Cette passerelle permet aux utilisateurs d'I2P-Bote de communiquer
avec les utilisateurs de messagerie standard sur l'Internet classique
et avec ceux qui utilisent le service i2pmail de postman
(@mail.i2p).</FONT><BR><FONT FACE="Arial, sans-serif"><BR>Pour
combattre les abus, il y a une limitation au nombre de messages que
vous pouvez envoyer vers Internet, comme avec le service normal de
postman&nbsp;: si un utilisateur d'I2P-Bote dépasse le quota de
messages envoyés, les messages supplémentaires sont retournés à
l'envoyeur.</FONT></P>
<P STYLE="line-height: 150%"><BR><BR><BR>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif"><B>3.
Considérations sur l'anonymat</B></FONT></P>
<P STYLE="line-height: 150%"><BR><FONT FACE="Arial, sans-serif">N'envoyez
pas d'informations susceptibles de vous identifier (nom, adresse,
situation géographique, fuseau horaire, horodatages, âge, sites web
que vous venez de visiter ou sur lesquels vous venez de parler sur un
blog, noms d'utilisateurs, adresses IP, identités de routeur I2P
routeur, de nœud I2P-Bote, numéros de sécurité sociale, de carte
de crédit, …, copies de passeport, de permis de conduire, de
contrats de location, de photos nu ou habillé , documents qui
contiennent votre nom comme auteur dans les réglages, et une
multitude d'autres) !</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif"><BR>Si
possible, </FONT>
</P>
<UL>
<LI><P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">laissez
I2P-Bote tourner 24h/24 7j/7,</FONT></P>
<LI><P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">utilisez
les routes de messagerie en conjonction avec les retards aléatoires
ou fixes par saut [<FONT COLOR="#ff0000">pas encore </FONT><FONT COLOR="#ff0000"><I>complètement</I></FONT><FONT COLOR="#ff0000">
implémenté</FONT>],</FONT></P>
<LI><P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">utilisez
un intervalle de relève long,</FONT></P>
<LI><P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">utilisez
un long retard pour vos propres paquets,</FONT></P>
<LI><P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">utilisez
un large intervalle de relève aléatoire [<FONT COLOR="#ff0000">pas
encore implémenté</FONT>].</FONT></P>
</UL>
<P STYLE="line-height: 150%"><BR><FONT FACE="Arial, sans-serif">Vous
pouvez supprimer l'envoi des horodatages des en-têtes de messages.</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Quand
vous répondez, certains marqueurs comme, «&nbsp;Rép: [Top
secret]&nbsp;» ou «&nbsp;[mégaphone] a écrit :&nbsp;» sont
ajoutés à votre réponse. Ils diffèrent d'une langue à l'autre,
suivant vos préférences de réglage de langue de l'interface
d'I2P-Bote. Cependant, si vous ne voulez pas que vos destinataires
puissent savoir comment vous avez effectué ce réglage (révélateur
de votre langue et peut-être de votre nationalité), vous pouvez
désactiver la traduction de ces marqueurs pour qu'il restent en
anglais, quelle que soit votre réglage de langue&nbsp;: Cochez la
case «&nbsp;Utiliser l'anglais pour les titres d'en-têtes de
messages sortants ('Re', 'wrote', etc.)&nbsp;».</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Soyez
prudent sur le contenu de vos envois! N'incluez pas d'information
personnelles ou des informations que vous seul pouvez posséder.
N'écrivez pas «&nbsp;je vais me coucher, il est tard&nbsp;»,
lorsque les tampons horaires ne sont pas désactivés.<BR>La langue
dans laquelle vous écrivez, votre style et vos particularités
d'expression sont autant d'autres éléments qui pourraient
intéresser un attaquant.</FONT></P>
<P STYLE="line-height: 150%"><BR><FONT FACE="Arial, sans-serif">I2P-Bote
permet aussi l'utilisation d'identités multiples. Supposez qu'un de
vos contacts découvre votre identité, car vous avez oublié
d'enlever une information vous concernant d'un document confidentiel
que vous lui avez transmis (par erreur ou pas). Maintenant, si ce
correspondant est amené a communiquer/collaborer avec d'autres de
vos contacts, il pourrait leur révéler l'identité réelle liée à
l'identité Bote qu'il connait de vous. Donc, si vous communiquez
avec ces autres avec la même adresse il vous reconnaitrons. Ils ne
pourraient pas si vous aviez utilisé une identité différente pour
vous adresser à eux.</FONT></P>
<P STYLE="line-height: 150%"><BR><BR><FONT FACE="Arial, sans-serif"><B>4.
Concept technique</B></FONT></P>
<P STYLE="line-height: 150%"><BR><FONT FACE="Arial, sans-serif">I2P-Bote
est un système de messagerie totalement décentralisé (sans
serveur) intra réseau crypté de bout en bout. Il supporte
l'utilisation d'identités multiples et n'expose pas les en-têtes de
messages. Il est actuellement encore en version alpha et ne peut être
utilisé que par son interface web intégré à la console du routeur
I2P. Il disposera bientôt du support de POP3, et il est prévu qu'il
garantisse un niveau d'anonymat supplémentaire via une option de
transport à haute latence. Tous les messages bote sont cryptés
automatiquement de bout en bout, de telle sorte qu'il ne soit pas
nécessaire d'utiliser un autre système de cryptage (bien que ça
soit possible), et les messages sont automatiquement authentifiés.
Comme il est décentralisé, il n'y a pas de serveur de messagerie
qui puisse établir de relation entre différentes identités en tant
qu'elles communiqueraient les unes avec les autres (profilage) : même
les nœuds relayant les messages ne connaissent pas l'expéditeur, et
hormis l'expéditeur et le destinataire, seuls le point terminal du
tunnel de messages à haute latence et les nœuds de stockage savent
à qui (identité anonyme) le message est destiné. L'expéditeur
peut être passé hors ligne depuis longtemps lorsque le message
devient disponible côté destinataire. Ceci améliore la classe
d'anonymat qui peut être atteinte par I2P-Bote. Pour ceux qui ne
veulent pas de longs retards, tous ces réglages sont accessibles à
l'utilisateur et chacun peut ainsi ajuster le niveau d'anonymat à
ses désirs.</FONT></P>
<P><FONT COLOR="#000000"><FONT FACE="Arial, sans-serif"><BR>Les
nœudsI2P-Bote stockent les messages cryptés dans une table de
hachage décentralisée (DHT) Kademlia. En conséquence, un message
peut être envoyé via de nombreux autres nœuds (relais) pour
augmenter la sécurité, ou directement sur un groupe de nœuds de
stockage pour une livraison plus rapide. Le même scenario s'applique
aussi à le relève des messages.<BR>(L'utilisation des routes de
message désactive automatiquement les tampons horaires)<BR>[</FONT></FONT><FONT COLOR="#ff0000"><FONT FACE="Arial, sans-serif">La
relève via les relais n'est pas encore implémentée</FONT></FONT><FONT COLOR="#000000"><FONT FACE="Arial, sans-serif">].</FONT></FONT></P>
<P><BR><BR>
</P>
<P STYLE="line-height: 150%"><FONT COLOR="#000000"><FONT FACE="Arial, sans-serif">Tous
les nœuds sont créés égaux : il n'y a pas de «&nbsp;super-nœuds&nbsp;»
ni de nœuds désignés comme relais ou stockeurs. Tout le monde agit
en tant que relais et stockage potentiels. L'utilisation d'espace
disque est configurable par l'utilisateur.</FONT></FONT></P>
<P STYLE="line-height: 150%"><FONT COLOR="#000000"><FONT FACE="Arial, sans-serif">Avant
qu'un message ne soit envoyé à un relais, il est découpé en
paquets et crypté avec la clé publique du destinataire. Ces paquets
sont stockés de façon redondante dans la DHT.</FONT></FONT></P>
<P STYLE="line-height: 150%"><FONT COLOR="#000000"><FONT FACE="Arial, sans-serif">Il
sont conservés au moins 100 jours, pendant lesquels le destinataire
peut les télécharger.</FONT></FONT></P>
<P STYLE="line-height: 150%"><FONT COLOR="#000000"><FONT FACE="Arial, sans-serif">Les
paquets relayés expirent aussi après 100 jours ou plus.</FONT></FONT></P>
<P STYLE="line-height: 150%"><FONT COLOR="#000000"><FONT FACE="Arial, sans-serif">Si
un nœud manque d'espace de stockage et qu'il n'y a pas de vieux
paquets à supprimer, ce nœud refuse les requêtes de stockage.</FONT></FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">De plus,
I2P-Bote nettoie les en-têtes de messages en n'autorisant que les
informations indispensables à la transmission, permettant ainsi
l'utilisation de clients de messagerie sans vérification préalable
de ce qu'ils ajoutent comme en-têtes bavardes [<FONT COLOR="#ff0000">POP3
pas encore implémenté</FONT>].</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Tout le
cryptage, le choix des chemins et le profilage sont effectués
localement en sorte qu'aucune tierce partie de confiance ne soit mise
à contribution.</FONT></P>
<P STYLE="font-weight: normal; line-height: 150%"><FONT FACE="Arial, sans-serif">Par
une utilisation appropriée d'I2P-Bote, c'est à dire en gardant à
l'esprit les considérations signalées plus haut relatives au bon
sens, personne ne saura qui vous êtes ni où vous vous trouvez. Et
si vous êtes déjà surveillé et que votre connexion Internet est
sur écoutes, le nuisible ne pourra pas savoir ce que vous envoyez ou
recevez, ni avec qui vous communiquez et où sont situés vos
correspondants.</FONT></P>
<P STYLE="line-height: 150%"><BR><BR>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif"><BR>Rentrons
un peu dans les détails&nbsp;:</FONT></P>
<P STYLE="line-height: 150%"><BR><BR>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif"><U>Ce
qu'I2P-Bote <I>cache</I> :</U></FONT></P>
<P STYLE="line-height: 150%"><BR><FONT FACE="Arial, sans-serif"><I>I2P-Bote
cache à la fois, l'identité et la situation de l'expéditeur et du
ou destinataires, celles des nœuds intermédiaires (relais et
stockage), le contenu des messages, leur taille, le nombre que vous
envoyez.</I></FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Seul le
destinataire peut connaître l'adresse de l'expéditeur du message
bote, et si ce dernier l'a décidé, même le destinataire peut être
tenu dans l'ignorance de cette donnée.</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Même si
envoyez des horodatages, votre fuseau horaire ne sera pas dévoilé.</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">De plus,
I2P-Bote masque ...</FONT></P>
<P STYLE="line-height: 150%">&nbsp;&nbsp;&nbsp; <FONT FACE="Arial, sans-serif">-
le fait que vous utilisez... I2P-Bote</FONT></P>
<P STYLE="line-height: 150%">&nbsp;&nbsp;&nbsp; <FONT FACE="Arial, sans-serif">-
le fait que vous envoyez un message</FONT></P>
<P STYLE="line-height: 150%">&nbsp;&nbsp;&nbsp; <FONT FACE="Arial, sans-serif">-
le fait que vous recevez un message</FONT></P>
<P STYLE="line-height: 150%">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT FACE="Arial, sans-serif">et
donc</FONT></P>
<P STYLE="line-height: 150%">&nbsp;&nbsp;&nbsp; <FONT FACE="Arial, sans-serif">-
le moment d'envoi d'un message</FONT></P>
<P STYLE="line-height: 150%">&nbsp;&nbsp;&nbsp; <FONT FACE="Arial, sans-serif">-
le moment de réception d'un message</FONT></P>
<P STYLE="line-height: 150%">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT FACE="Arial, sans-serif">ainsi
que</FONT></P>
<P STYLE="line-height: 150%">&nbsp;&nbsp;&nbsp; <FONT FACE="Arial, sans-serif">-
la limite supérieure du nombre de messages qu'un utilisateur inconnu
reçoit, - nota bene : un utilisateur abstrait, pas un concret,
extrapolant simplement son existence de celle de la destination de
messagerie<BR>&nbsp;&nbsp;&nbsp; - car il pourrait toujours avoir
plus d'une identité ; et la limite basse, car une identité envoie
également des messages de test et des messages leurres/«&nbsp;bidons&nbsp;»</FONT></P>
<P STYLE="line-height: 150%"><BR><BR>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif"><U>Ce
qu'I2P-Bote <I>masque partiellement</I> : </U></FONT>
</P>
<P STYLE="line-height: 150%"><BR><FONT FACE="Arial, sans-serif">L'adresse
I2P-Bote du destinataire n'est connue que par l'expéditeur et le(s)
destinataire(s). </FONT>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">En cas de
destinataires multiples, chacun verra tous les autres destinataires
dont les adresses ont été indiquées en «&nbsp;A&nbsp;:» OU
«&nbsp;Cc&nbsp;:&nbsp;».</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Toutes
les entrées «&nbsp;Cci&nbsp;:&nbsp;» ne sont visibles qu'à
l'expéditeur et au destinataire spécifique. </FONT>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Le moment
de l'envoi, s'il est précisé, n'est visible que par l'expéditeur
et le destinataire.</FONT></P>
<P STYLE="line-height: 150%"><BR><BR><FONT FACE="Arial, sans-serif"><U>Ce
qu'I2P-Bote </U></FONT><FONT FACE="Arial, sans-serif"><I><U>peut
masquer optionnellement </U></I></FONT><FONT FACE="Arial, sans-serif"><U>:
</U></FONT>
</P>
<P STYLE="line-height: 150%"><BR><FONT FACE="Arial, sans-serif">- Si
les routes de messagerie sont utilisées, le moment de l'envoi d'un
message</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">- Si les
routes de messagerie sont utilisées, le moment de relève d'un
message [<FONT COLOR="#ff0000">pas encore implémenté</FONT>].</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">- Si
l'expéditeur supprime les horodatages, seul l'expéditeur sait quand
il a envoyé un message.</FONT></P>
<P STYLE="line-height: 150%"><BR><BR><FONT FACE="Arial, sans-serif"><U>Ce
qu'I2P-Bote </U></FONT><FONT FACE="Arial, sans-serif"><I><U>ne peut
pas cacher </U></I></FONT><FONT FACE="Arial, sans-serif"><U>: </U></FONT>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif"><BR>I2P-Bote
ne peut pas masquer la fréquence à laquelle une identité donnée
relève les nouveaux messages, ni ne nombre de messages reçus par
une identité donnée.</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif"><BR>Pour
son démarrage, I2P-Bote ne dépend pas non-plus d'un nœud central
car il utilise Seedless.</FONT></P>
<P STYLE="line-height: 150%"><BR><BR><BR>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif"><B>5
Terminologie/Glossaire:</B></FONT></P>
<P STYLE="line-height: 150%"><BR><BR>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif"><I><U>Identité
du routeur/nœud I2P-Bote </U>:</I></FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">C'est
l'identité par laquelle le routeur I2P-Bote est connu. Elle est
utilisée pour contacter ce routeur, pour stocker, relayer et relever
les messages, mais aussi pour le cryptage par saut et le contacter
via I2P, car c'est celle là même de la destination du tunnel I2P.
Elle est affichée pour représenter le nœud I2P-Bote dans les
statistiques.</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Ainsi
donc, l'identité du routeur (I2P-Bote) correspond à la destination
I2P (l'adresse d'un nœud I2P-Bote sur le réseau I2P il n'y a
pas de nécessité de la connaître, sauf en cas de problèmes de
connexion aux autres nœuds I2P-Bote).</FONT></P>
<P STYLE="font-weight: normal; line-height: 150%"><BR><FONT FACE="Arial, sans-serif"><I><U>Destination
de messagerie I2P-Bote :</U></I></FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">La
destination de messagerie I2P-Bote (clé) est un identifiant par
lequel quelqu'un peut être atteint via I2P-Bote, comme son nom
l'indique&nbsp;: une destination e-mail. C'est donc pour I2P-Bote ce
qu'est une adresse e-mail pour un système de messagerie standard&nbsp;:
la destination de messagerie est l'adresse effective d'envoi de
messages, de stockage et de relève dans la DHT. <BR>Elle est aussi
utilisée pour le cryptage de bout en bout des messages, pour les
informations d'en-têtes et les pièces jointes. </FONT>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Une
destination de messagerie I2P-Bote est une chaîne en base 64
contenant une clé publique de cryptage et une clé de vérification
de signature, par exemple&nbsp;: </FONT>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">uQtdwFHqbWHGyxZN8wChjWbCcgWrKuoBRNoziEpE8XDt8koHdJiskYXeUyq7JmpG</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">In8WKXY5LNue~62IXeZ-ppUYDdqi5V~9BZrcbpvgb5tjuu3ZRtHq9Vn6T9hOO1fa</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">FYZbK-FqHRiKm~lewFjSmfbBf1e6Fb~FLwQqUBTMtKYrRdO1d3xVIm2XXK83k1Da</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">-nufGASLaHJfsEkwMMDngg8uqRQmoj0THJb6vRfXzRw4qR5a0nj6dodeBfl2NgL9</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">HfOLInwrD67haJqjFJ8r~vVyOxRDJYFE8~f9b7k3N0YeyUK4RJSoiPXtTBLQ2RFQ</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">gOaKg4CuKHE0KCigBRU-Fhhc4weUzyU-g~rbTc2SWPlfvZ6n0voSvhvkZI9V52X3</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">SptDXk3fAEcwnC7lZzza6RNHurSMDMyOTmppAVz6BD8PB4o4RuWq7MQcnF9znElp</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">HX3Q10QdV3omVZJDNPxo-Wf~CpEd88C9ga4pS~QGIHSWtMPLFazeGeSHCnPzIRYD</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif"><BR>L'identité
de routeur/nœud I2P-Bote et la destination de messagerie I2P-Bote se
ressemblent mais elles sont complètement indépendantes l'une de
l'autre.</FONT></P>
<P STYLE="line-height: 150%"><BR><FONT FACE="Arial, sans-serif"><I><U>Adresse
e-mail :</U></I></FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Les
adresses e-mail dans I2P-Bote sont des raccourcis des destinations de
messagerie.</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Les
correspondances entre elles sont stockées à deux endroits&nbsp;: le
carnet d'adresses local et l'annuaire d'adresses décentralisé [<FONT COLOR="#ff0000">ce
dernier n'est pas encore implémenté</FONT>].</FONT></P>
<P STYLE="line-height: 150%"><BR><FONT FACE="Arial, sans-serif"><I><U>Identité
de messagerie I2P-Bote :</U></I></FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">L'identité
de messagerie I2P-Bote est un porte clé de destination de messagerie
I2P-Bote avec la clé privée correspondante et le nom que lui a
donné l'utilisateur qui l'a créé. Ce nom sera envoyé avec la clé
de destination si vous ne désactivez pas l'envoi de cette
information sur l'expéditeur.</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Elle ne
sera visible que par le destinataire s'il n'a pas déjà un nom pour
cette destination dans son propre carnet d'adresses local.</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Donc en
termes techniques, une identité de messagerie est constituée de
quatre éléments&nbsp;:</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">* une
destination de messagerie (c'est à dire deux clés publiques)</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">* les
deux clés privées correspondantes</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">* un nom
public qui peut être montré aux correspondants</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">* une
description qui n'est accessible qu'à vous même, le créateur
l'identité.</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">(Pour
vous aider à vous souvenir de l'usage que vous assignez à cette
identité).</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Une
identité n'est pas pas nécessaire pour envoyer des messages (dans
ce cas, seul «&nbsp;Anonyme&nbsp;» est proposé comme expéditeur
dans le champ de sélection).</FONT></P>
<P STYLE="line-height: 150%"><BR><BR>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif"><I><U>Routes
de messagerie </U></I>:</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Les
routes de messagerie sont un mode de transport à haute latence
supplémentaire pour I2P-Bote. Pour son fonctionnement, une chaîne
de nœuds I2P-Bote est construite, agissant en tant que routeurs
relais pour les paquets et obéissant à des retards par saut [<FONT COLOR="#ff0000">les
retards individuels par saut ne sont pas encore implémentés</FONT>]&nbsp;;
</FONT>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif"><B><BR>AVERTISSEMENT!</B></FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Si vous
choisissez cette option particulièrement avec de nombreux sauts
et/ou de longs retards, ne soyez pas surpris si vos messages
n'arrivent pas rapidement à destination. Ça prendra évidemment
plus de temps jusqu'à plusieurs jours !</FONT></P>
<P STYLE="line-height: 150%"><BR><BR>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif"><I><B>6.&nbsp;
Remerciements</B></I></FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Idée &amp;
conception technique : HungryHobo, Mixxy </FONT>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Implémentation
: HungryHobo </FONT>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Maintenance
du greffon : zzz, HungryHobo </FONT>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Interface
utilisateur : HungryHobo </FONT>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Intégration
de Seedless : sponge </FONT>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Traduction
allemande : HungryHobo </FONT>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Traduction
russe : suhr</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Traduction
française : albat, Redzara, Mixxy, magma </FONT>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Traduction
espagnole : Mixxy</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Traduction
portugaise : Mixxy </FONT>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Traduction
hollandaise : KwukDuck </FONT>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Traduction
norvégienne : hej </FONT>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Traduction
suédoise : hottuna</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Traduction
chinoise : walking </FONT>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Traduction
arabe : hamada </FONT>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Testeurs
versions Alpha : HungryHobo, Mixxy, Returning Novice, sponge, et de
nombreux autres. </FONT>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Manuel :
Mixxy</FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">Testeurs
versions Alpha : HungryHobo, Mixxy, Returning Novice, sponge, and
many others</FONT></P>
<P STYLE="line-height: 150%">Traduction française du manuel&nbsp;:
magma (avril 2011) (grâce à l'aide inestimable de user pour la
restitution correcte des concepts techniques et l'utilisation des
outils techniques de l'équipe I2P).</P>
<P STYLE="line-height: 150%"><BR><BR>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif"><B>7.
Détails techniques</B></FONT></P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif">-- voir
techdoc.txt --</FONT></P>
<P STYLE="line-height: 150%"><BR><BR>
</P>
<P STYLE="line-height: 150%"><BR><BR>
</P>
<P STYLE="line-height: 150%"><FONT FACE="Arial, sans-serif"><I><B>ENJOY
THE BOTE FEELING!!</B></I></FONT></P>
</BODY>
</HTML>

View File

@ -1,2 +0,0 @@
REM This scrypt only works if I2P is installed in the standard directory
@java -cp "%PROGRAMFILES%\\i2p\\lib\\i2p.jar;i2pbote.jar" i2p.bote.fileencryption.Decrypt %*

View File

@ -1,2 +0,0 @@
#!/bin/sh
java -cp $I2P/lib/i2p.jar:`dirname $0`/i2pbote.jar i2p.bote.fileencryption.Decrypt $@

View File

@ -1,2 +0,0 @@
REM This scrypt only works if I2P is installed in the standard directory
@java -cp "%PROGRAMFILES%\\i2p\\lib\\i2p.jar;i2pbote.jar" i2p.bote.fileencryption.Encrypt %*

View File

@ -1,2 +0,0 @@
#!/bin/sh
java -cp $I2P/lib/i2p.jar:`dirname $0`/i2pbote.jar i2p.bote.fileencryption.Encrypt $@

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 298 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 852 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 780 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 564 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 794 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 227 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 803 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -1,73 +0,0 @@
<%--
Copyright (C) 2009 HungryHobo@mail.i2p
The GPG fingerprint for HungryHobo@mail.i2p is:
6DD3 EAA2 9990 29BC 4AD2 7486 1E2C 7B61 76DC DC12
This file is part of I2P-Bote.
I2P-Bote is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
I2P-Bote is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with I2P-Bote. If not, see <http://www.gnu.org/licenses/>.
--%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="ib" uri="I2pBoteTags" %>
<ib:message key="Set Password" var="title" scope="request"/>
<c:if test="${param.action eq 'set'}">
<c:set var="errorMessage" value="${ib:changePassword(param.old, param.new, param.confirm)}" scope="request"/>
<c:if test="${empty errorMessage}">
<ib:message key="The password has been changed." var="infoMessage" scope="request"/>
<jsp:forward page="index.jsp"/>
</c:if>
</c:if>
<jsp:include page="header.jsp"/>
<div class="main">
<h2><ib:message key="Set a new Password"/></h2>
<p>
<ib:message key="If you have not set a password, leave the old password blank."/>
</p><p>
<ib:message>
Please note that if a password is set, emails cannot be checked automatically
but only when the Check Mail button is clicked.
</ib:message>
</p><br/>
<form name="form" action="setPassword.jsp" method="POST">
<input type="hidden" name="action" value="set"/>
<div class="password-label"><ib:message key="Old password:"/></div>
<div class="password-field"><input type="password" name="old"/></div>
<div class="password-label"><ib:message key="New password:"/></div>
<div class="password-field"><input type="password" name="new"/></div>
<div class="password-label"><ib:message key="Confirm:"/></div>
<div class="password-field"><input type="password" name="confirm"/></div>
<p/>
<ib:message key="OK" var="ok"/>
<input type="submit" value="${ok}"/>
</form>
<script type="text/javascript" language="JavaScript">
document.forms['form'].elements['old'].focus();
</script>
</div>
<jsp:include page="footer.jsp"/>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 209 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 209 B

592
build.xml
View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<project basedir="." default="help" name="I2P-Bote">
<project basedir="." default="help" name="I2P-Bote" xmlns:if="ant:if" xmlns:unless="ant:unless">
<property environment="env"/>
<condition property="i2pbase" value="${env.I2P}">
<isset property="env.I2P"/>
@ -7,15 +7,98 @@
<property name="i2plib" value="${i2pbase}/lib"/>
<property name="jstllib" value="${i2pbase}/apps/susidns/src/WEB-INF/lib"/>
<property name="lib" value="WebContent/WEB-INF/lib"/>
<property name="lib" value="lib"/>
<property name="makeplugin" value="../i2p.scripts/plugin/makeplugin.sh"/>
<property name="junit.filename" value="junit-4.8.1.jar"/>
<property name="junit.url" value="http://sourceforge.net/projects/junit/files/junit/4.8.1/junit-4.8.1.jar/download"/>
<property name="mockito.filename" value="mockito-core-2.0.31-beta.jar"/>
<property name="mockito.url" value="https://bintray.com/artifact/download/szczepiq/maven/org/mockito/mockito-core/2.0.31-beta/mockito-core-2.0.31-beta.jar"/>
<!-- Just the main jMock .jar, the .zip contains this and dependencies -->
<property name="jmock.filename" value="jmock-2.6.0.jar"/>
<property name="jmock.archive" value="jmock-2.6.0-jars.zip"/>
<property name="jmockcp" value="${lib}/jmock-2.6.0.jar:${lib}/hamcrest-core-1.3.jar:${lib}/hamcrest-library-1.3.jar:${lib}/jmock-legacy-2.6.0.jar:${lib}/cglib-nodep-2.2.3.jar:${lib}/objenesis-1.0.jar"/>
<property name="jmock.url" value="http://jmock.org/downloads/${jmock.archive}"/>
<!-- Dependencies -->
<!-- Local -->
<property name="ntruenc.filename" value="ntruenc-1.2.jar"/>
<property name="ntruenc.includeinupdate" value="false"/>
<property name="scrypt.filename" value="scrypt-1.4.0.jar"/>
<property name="scrypt.includeinupdate" value="false"/>
<property name="lzma.filename" value="lzma-9.20.jar"/>
<property name="lzma.includeinupdate" value="false"/>
<property name="gmss.filename" value="flexi-gmss-1.7p1.jar"/>
<property name="gmss.includeinupdate" value="false"/>
<property name="jcommon.filename" value="jcommon-1.0.23.jar"/>
<property name="jcommon.includeinupdate" value="false"/>
<property name="jfreechart.filename" value="jfreechart-1.0.19.jar"/>
<property name="jfreechart.includeinupdate" value="false"/>
<!-- JavaMail -->
<property name="mailapi.name" value="JavaMail"/>
<property name="mailapi.filename" value="mailapi-1.5.4.jar"/>
<property name="mailapi.hash" value="6786437244ec10d05601c52ee418b33e31f7ce5ed2cad8c8893139b28cb18ac3"/>
<property name="mailapi.url" value="https://maven.java.net/content/repositories/releases/com/sun/mail/mailapi/1.5.4/mailapi-1.5.4.jar"/>
<property name="mailapi.includeinupdate" value="false"/>
<!-- BouncyCastle Provider -->
<property name="bcprov.name" value="BouncyCastle Provider"/>
<property name="bcprov.filename" value="bcprov-jdk15on-152.jar"/>
<property name="bcprov.hash" value="0dc4d181e4d347893c2ddbd2e6cd5d7287fc651c03648fa64b2341c7366b1773"/>
<property name="bcprov.url" value="http://downloads.bouncycastle.org/java/bcprov-jdk15on-152.jar"/>
<property name="bcprov.includeinupdate" value="false"/>
<!-- Apache James IMAP server -->
<!-- Just one of the James .jars for checking presence of James, the .zip contains this and dependencies -->
<property name="james.filename" value="apache-james-mailbox-api-0.6-20150508.040939-710.jar"/>
<property name="james.archive" value="james-server-app-3.0.0-beta5-20150627.102412-1076-app.zip"/>
<!--
James snapshots are only kept for a few days. The URL below points to a copy of the 6/27/2015 snapshot.
To be replaced with a repository.apache.org URL once beta5 is out.
-->
<property name="james.url" value="http://download.i2p2.de/mirror/lib/james-server-app-3.0.0-beta5-20150627.102412-1076-app.zip"/>
<property name="james.includeinupdate" value="false"/>
<!-- SubEtha SMTP -->
<property name="subetha.name" value="SubEtha SMTP"/>
<property name="subetha.filename" value="subethasmtp-3.1.7.jar"/>
<property name="subetha.hash" value="95cf031f1bc1b1a69b08554fbf8970bad994b32db32388d482c6afb482f1db76"/>
<property name="subetha.archive" value="subethasmtp-3.1.7.zip"/>
<property name="subetha.url" value="http://subethasmtp.googlecode.com/files/subethasmtp-3.1.7.zip"/>
<property name="subetha.includeinupdate" value="false"/>
<!-- the following are only used by win32installer -->
<property name="i2p.mtn" value="../i2p.mtn"/>
<property name="win32launcherurl" value="http://dist.codehaus.org/izpack/native-launcher/izpack-launcher-1.3.zip"/>
<property name="win32jreurl" value="http://javadl.sun.com/webapps/download/AutoDL?BundleId=47363"/>
<fileset dir="${lib}" id="imaplibs">
<include name="apache-james-mailbox-api-0.6-20150508.040939-710.jar"/>
<include name="apache-james-mailbox-store-0.6-20150508.041003-704.jar"/>
<include name="apache-mime4j-core-0.8.0-20150617.024907-738.jar"/>
<include name="apache-mime4j-dom-0.8.0-20150617.024927-735.jar"/>
<include name="commons-codec-1.7.jar"/>
<include name="commons-collections-3.2.1.jar"/>
<include name="commons-configuration-1.9.jar"/>
<include name="commons-io-2.4.jar"/>
<include name="commons-lang-2.6.jar"/>
<include name="james-server-filesystem-api-3.0.0-beta5-SNAPSHOT.jar"/>
<include name="james-server-lifecycle-api-3.0.0-beta5-SNAPSHOT.jar"/>
<include name="james-server-protocols-imap4-3.0.0-beta5-SNAPSHOT.jar"/>
<include name="james-server-protocols-library-3.0.0-beta5-SNAPSHOT.jar"/>
<include name="james-server-util-3.0.0-beta5-SNAPSHOT.jar"/>
<include name="jutf7-1.0.0.jar"/>
<include name="log4j-1.2.17.jar"/>
<include name="netty-3.3.1.Final.jar"/>
<include name="protocols-api-1.6.4-20150617.121129-1080.jar"/>
<include name="protocols-imap-1.6.4-20150617.121245-927.jar"/>
<include name="protocols-netty-1.6.4-20150617.121137-1044.jar"/>
<include name="slf4j-api-1.7.2.jar"/>
<include name="slf4j-log4j12-1.7.2.jar"/>
</fileset>
<path id="cp">
<pathelement path="${java.class.path}" />
<pathelement location="${i2plib}/i2p.jar" />
<pathelement location="${i2plib}/mstreaming.jar" />
<pathelement location="${i2plib}/streaming.jar" />
<pathelement location="${i2plib}/router.jar" />
<!-- <pathelement location="${i2plib}/i2ptunnel.jar" /> -->
<pathelement location="${i2plib}/org.mortbay.jetty.jar"/>
<pathelement location="${i2plib}/jasper-compiler.jar" />
<pathelement location="${i2plib}/jasper-runtime.jar" />
@ -24,25 +107,26 @@
<pathelement location="${i2plib}/commons-el.jar" />
<pathelement location="${i2plib}/jstl.jar" />
<pathelement location="${i2plib}/standard.jar" />
<pathelement location="${lib}/mailapi.jar" />
<pathelement location="${lib}/bcprov-ecc-jdk16-146.jar" />
<pathelement location="${lib}/ntruenc-1.2.jar" />
<pathelement location="${lib}/scrypt-1.3.3.jar" />
<pathelement location="${lib}/lzma-9.20.jar" />
<pathelement location="${lib}/flexi-gmss-1.7p1.jar" />
<pathelement location="${lib}/${mailapi.filename}" />
<pathelement location="${lib}/${bcprov.filename}" />
<pathelement location="${lib}/${ntruenc.filename}" />
<pathelement location="${lib}/${scrypt.filename}" />
<pathelement location="${lib}/${lzma.filename}" />
<pathelement location="${lib}/${gmss.filename}" />
<pathelement location="${lib}/${subetha.filename}" />
<pathelement location="${lib}/${jcommon.filename}" />
<pathelement location="${lib}/${jfreechart.filename}" />
<pathelement location="src/main/webapp/WEB-INF/classes" />
<fileset refid="imaplibs"/>
</path>
<property name="junit.filename" value="junit-4.8.1.jar"/>
<property name="junit.url" value="http://sourceforge.net/projects/junit/files/junit/4.8.1/junit-4.8.1.jar/download"/>
<!-- Just the main jMock .jar, the .zip contains this and dependencies -->
<property name="jmock.filename" value="jmock-2.5.1.jar"/>
<property name="jmock.archive" value="jmock-2.5.1-jars.zip"/>
<property name="jmockcp" value="${lib}/jmock-2.5.1.jar:${lib}/hamcrest-core-1.1.jar:${lib}/hamcrest-library-1.1.jar:${lib}/jmock-legacy-2.5.1.jar:${lib}/cglib-nodep-2.1_3.jar:${lib}/objenesis-1.0.jar"/>
<property name="jmock.url" value="http://www.jmock.org/dist/${jmock.archive}"/>
<!-- the following are only used by win32installer -->
<property name="i2p.mtn" value="../i2p.mtn"/>
<property name="win32launcherurl" value="http://dist.codehaus.org/izpack/native-launcher/izpack-launcher-1.3.zip"/>
<property name="win32jreurl" value="http://javadl.sun.com/webapps/download/AutoDL?BundleId=47363"/>
<pathconvert property="manifest.classpath" pathsep=" ">
<path refid="cp" />
<mapper>
<flattenmapper />
</mapper>
</pathconvert>
<target name="help">
<echo message="Useful targets:" />
@ -63,6 +147,7 @@
<echo message=" junit: Runs all unit tests" />
<echo message=" javadoc: Generates code documentation in the javadoc dir" />
<echo message=" clean: Removes all generated files and directories" />
<echo message=" distclean: Removes all generated files and directories, and all downloaded libraries" />
</target>
<target name="all" depends="clean, src, war, plugin" />
@ -71,12 +156,41 @@
<fail unless="i2pbase" message="The I2P environment variable is not set.${line.separator}It must point to an I2P installation. It is usually a path of the form ${line.separator}/xxx/yyy/i2p."/>
</target>
<!-- compiles everything under src/, but not test/ or ant/ -->
<target name="compile" depends="checki2pbase">
<macrodef name="checkdep">
<attribute name="dep"/>
<sequential>
<local name="hashValid"/>
<checksum file="${lib}/${@{dep}.filename}" algorithm="SHA-256" property="${@{dep}.hash}" verifyProperty="hashValid"/>
<fail message="The ${@{dep}.name} library has an invalid hash.">
<condition>
<isfalse value="${hashValid}"/>
</condition>
</fail>
</sequential>
</macrodef>
<target name="checkdependencies">
<available property="mailapiexists" file="${lib}/${mailapi.filename}" type="file"/>
<available property="bcprovexists" file="${lib}/${bcprov.filename}" type="file"/>
<available property="jamesexists" file="${lib}/${james.filename}" type="file"/>
<available property="subethaexists" file="${lib}/${subetha.filename}" type="file"/>
<ant target="downloadmailapi"/>
<ant target="downloadbcprov"/>
<ant target="downloadjames"/>
<ant target="downloadsubetha"/>
<checkdep dep="mailapi"/>
<checkdep dep="bcprov"/>
<checkdep dep="subetha"/>
</target>
<!-- compiles everything under src/main/java, but not src/test/ or src/build/ -->
<target name="compile" depends="checki2pbase, checkdependencies">
<mkdir dir="./ant_build" />
<mkdir dir="./ant_build/classes" />
<javac
srcdir="./src"
srcdir="./src/main/java"
debug="true"
deprecation="on"
source="1.6" target="1.6"
@ -102,7 +216,7 @@
<arg value="-webinc" />
<arg value="ant_build/web-fragment.xml" />
<arg value="-webapp" />
<arg value="WebContent" />
<arg value="src/main/webapp" />
</java>
<javac
@ -115,7 +229,7 @@
includes="**/*.java"
classpathref="jspcp"
failonerror="true" />
<copy file="WebContent/WEB-INF/web.xml" tofile="ant_build/web.xml" />
<copy file="src/main/webapp/WEB-INF/web.xml" tofile="ant_build/web.xml" />
<loadfile property="jspc.web.fragment" srcfile="ant_build/web-fragment.xml" />
<replace file="ant_build/web.xml">
<replacefilter token="&lt;!-- precompiled servlets --&gt;" value="${jspc.web.fragment}" />
@ -126,19 +240,20 @@
<mkdir dir="ant_build" />
<war destfile="i2pbote.war" webxml="ant_build/web.xml">
<classes dir="ant_build/classes" includes="i2p/bote/web/** i2p/bote/jsp/** org/apache/jsp/**" />
<fileset dir="WebContent" includes="*.html"/>
<fileset dir="WebContent" includes="*.css"/>
<fileset dir="WebContent/" includes="*.xml"/>
<webinf dir="WebContent/WEB-INF/tlds" includes="*.tld"/>
<fileset dir="src/main/webapp" includes="*.html"/>
<fileset dir="src/main/webapp/" includes="*.xml"/>
<webinf dir="src/main/webapp/WEB-INF/tlds" includes="*.tld"/>
<lib file="${lib}/i2pbote.jar"/>
<lib file="${lib}/mailapi.jar"/>
<lib file="${lib}/bcprov-ecc-jdk16-146.jar"/>
<lib file="${lib}/ntruenc-1.2.jar"/>
<lib file="${lib}/scrypt-1.3.3.jar"/>
<lib file="${lib}/lzma-9.20.jar"/>
<lib file="${lib}/flexi-gmss-1.7p1.jar"/>
<zipfileset dir="WebContent/images" prefix="images"/>
<zipfileset dir="WebContent/themes" prefix="themes"/>
<lib file="${lib}/${mailapi.filename}"/>
<lib file="${lib}/${bcprov.filename}"/>
<lib file="${lib}/${ntruenc.filename}"/>
<lib file="${lib}/${scrypt.filename}"/>
<lib file="${lib}/${lzma.filename"/>
<lib file="${lib}/${gmss.filename}"/>
<lib file="${lib}/${jcommon.filename}" />
<lib file="${lib}/${jfreechart.filename}" />
<zipfileset dir="src/main/webapp/html" prefix="html"/>
<zipfileset dir="src/main/webapp/themes" prefix="themes"/>
</war>
<echo message="SHA256 sum:"/>
@ -151,14 +266,39 @@
<mkdir dir="ant_build" />
<jar destfile="${lib}/i2pbote.jar">
<fileset dir="ant_build/classes" excludes="i2p/bote/web/** i2p/bote/jsp/** org/apache/jsp/** codec/** **/*Test.class"/>
<fileset dir="src" includes="i2p/bote/network/built-in-peers.txt"/>
<fileset dir="src" includes="i2p/bote/crypto/wordlist/"/>
<fileset dir="src/main/java" includes="i2p/bote/network/built-in-peers.txt"/>
<fileset dir="src/main/java" includes="i2p/bote/crypto/wordlist/"/>
<manifest>
<attribute name="Class-Path" value="${manifest.classpath}" />
</manifest>
<metainf file="src/main/webapp/META-INF/mime.types"/>
</jar>
</target>
<macrodef name="packdep">
<attribute name="dep"/>
<element name="exec-args" optional="yes" implicit="yes"/>
<sequential>
<exec executable="pack200" failonerror="true">
<arg value="--no-gzip"/>
<arg value="--effort=9"/>
<arg value="--modification-time=latest"/>
<exec-args/>
<arg value="plugin/plugin.tmp/lib/${@{dep}.filename}.pack"/>
<arg value="${lib}/${@{dep}.filename}"/>
</exec>
</sequential>
</macrodef>
<macrodef name="removepack">
<attribute name="dep"/>
<sequential>
<delete file="plugin/plugin.tmp/lib/${@{dep}.filename}"/>
<delete file="plugin/plugin.tmp/lib/${@{dep}.filename}.pack"/>
</sequential>
</macrodef>
<!--
- Make two plugins, one for initial installs and one for updates.
- Only the initial install includes mailapi.jar.
- Neither includes jstl.jar or standard.jar, as any i2p version that has
- plugin support has these two jars pulled out of susidns.war and put in
- $I2P/lib. We set the classpath in webapps.config to find them.
@ -185,51 +325,26 @@
<arg value="plugin/plugin.tmp/lib/i2pbote.jar.pack"/>
<arg value="${lib}/i2pbote.jar"/>
</exec>
<exec executable="pack200" failonerror="true">
<arg value="--no-gzip"/>
<arg value="--effort=9"/>
<arg value="--modification-time=latest"/>
<arg value="plugin/plugin.tmp/lib/bcprov-ecc-jdk16-146.jar.pack"/>
<arg value="${lib}/bcprov-ecc-jdk16-146.jar"/>
</exec>
<exec executable="pack200" failonerror="true">
<arg value="--no-gzip"/>
<arg value="--effort=9"/>
<arg value="--modification-time=latest"/>
<arg value="plugin/plugin.tmp/lib/ntruenc-1.2.jar.pack"/>
<arg value="${lib}/ntruenc-1.2.jar"/>
</exec>
<exec executable="pack200" failonerror="true">
<arg value="--no-gzip"/>
<arg value="--effort=9"/>
<arg value="--modification-time=latest"/>
<arg value="plugin/plugin.tmp/lib/scrypt-1.3.3.jar.pack"/>
<arg value="${lib}/scrypt-1.3.3.jar"/>
</exec>
<exec executable="pack200" failonerror="true">
<arg value="--no-gzip"/>
<arg value="--effort=9"/>
<arg value="--modification-time=latest"/>
<arg value="plugin/plugin.tmp/lib/lzma-9.20.jar.pack"/>
<arg value="${lib}/lzma-9.20.jar"/>
</exec>
<exec executable="pack200" failonerror="true">
<arg value="--no-gzip"/>
<arg value="--effort=9"/>
<arg value="--modification-time=latest"/>
<arg value="plugin/plugin.tmp/lib/flexi-gmss-1.7p1.jar.pack"/>
<arg value="${lib}/flexi-gmss-1.7p1.jar"/>
</exec>
<copy file="WebContent/WEB-INF/lib/encrypt.sh" todir="plugin/plugin.tmp/lib"/>
<copy file="WebContent/WEB-INF/lib/decrypt.sh" todir="plugin/plugin.tmp/lib"/>
<copy file="WebContent/WEB-INF/lib/fileinfo.sh" todir="plugin/plugin.tmp/lib"/>
<copy file="WebContent/WEB-INF/lib/encrypt.bat" todir="plugin/plugin.tmp/lib"/>
<copy file="WebContent/WEB-INF/lib/decrypt.bat" todir="plugin/plugin.tmp/lib"/>
<copy file="WebContent/WEB-INF/lib/fileinfo.bat" todir="plugin/plugin.tmp/lib"/>
<!-- pack local dependencies in updater -->
<includedep updater="true" dep="ntruenc"/>
<includedep updater="true" dep="scrypt"/>
<includedep updater="true" dep="lzma"/>
<includedep updater="true" dep="gmss"/>
<includedep updater="true" dep="jcommon"/>
<includedep updater="true" dep="jfreechart"/>
<!-- pack remote dependencies in updater -->
<includedep updater="true" dep="mailapi"/>
<includedep updater="true" dep="bcprov"/>
<includedep updater="true" dep="james"/>
<includedep updater="true" dep="subetha"/>
<delete file="plugin/plugin.tmp/lib/mailapi.jar" />
<delete file="plugin/plugin.tmp/lib/mailapi.jar.pack" />
<copy file="src/main/scripts/encrypt.sh" todir="plugin/plugin.tmp/lib"/>
<copy file="src/main/scripts/decrypt.sh" todir="plugin/plugin.tmp/lib"/>
<copy file="src/main/scripts/fileinfo.sh" todir="plugin/plugin.tmp/lib"/>
<copy file="src/main/scripts/encrypt.bat" todir="plugin/plugin.tmp/lib"/>
<copy file="src/main/scripts/decrypt.bat" todir="plugin/plugin.tmp/lib"/>
<copy file="src/main/scripts/fileinfo.bat" todir="plugin/plugin.tmp/lib"/>
<!-- get build number -->
<buildnumber file="plugin/build.number" />
@ -237,29 +352,42 @@
<!-- make the update xpi2p -->
<copy file="plugin/plugin.config" todir="plugin/plugin.tmp" overwrite="true" />
<exec executable="echo" osfamily="unix" failonerror="true" output="plugin/plugin.tmp/plugin.config" append="true">
<arg value="version=${version}-b${build.number}" />
<arg value="version=${version}" />
</exec>
<exec executable="echo" osfamily="unix" failonerror="true" output="plugin/plugin.tmp/plugin.config" append="true">
<arg value="update-only=true" />
</exec>
<exec executable="${makeplugin}" failonerror="true" >
<input message="Enter key password for plugin-su3-keystore.ks:" addproperty="release.password.su3" />
<fail message="You must enter a password." >
<condition>
<equals arg1="${release.password.su3}" arg2=""/>
</condition>
</fail>
<exec executable="${makeplugin}" inputstring="${release.password.su3}" failonerror="true" >
<arg value="plugin/plugin.tmp" />
</exec>
<move file="i2pbote.xpi2p" tofile="i2pbote-update.xpi2p" />
<move file="i2pbote.su3" tofile="i2pbote-update.su3" />
<!-- pack local dependencies in installer -->
<includedep dep="ntruenc"/>
<includedep dep="scrypt"/>
<includedep dep="lzma"/>
<includedep dep="gmss"/>
<includedep dep="jcommon"/>
<includedep dep="jfreechart"/>
<!-- pack remote dependencies in installer -->
<includedep dep="mailapi"/>
<includedep dep="bcprov"/>
<includedep dep="james"/>
<includedep dep="subetha"/>
<!-- make the install xpi2p -->
<exec executable="pack200" failonerror="true">
<arg value="--no-gzip"/>
<arg value="--effort=9"/>
<arg value="--modification-time=latest"/>
<arg value="plugin/plugin.tmp/lib/mailapi.jar.pack"/>
<arg value="${lib}/mailapi.jar"/>
</exec>
<copy file="plugin/plugin.config" todir="plugin/plugin.tmp" overwrite="true" />
<exec executable="echo" osfamily="unix" failonerror="true" output="plugin/plugin.tmp/plugin.config" append="true">
<arg value="version=${version}-b${build.number}" />
<arg value="version=${version}" />
</exec>
<exec executable="${makeplugin}" >
<exec executable="${makeplugin}" inputstring="${release.password.su3}" failonerror="true" >
<arg value="plugin/plugin.tmp" />
</exec>
</target>
@ -269,26 +397,144 @@
<mkdir dir="ant_build" />
<war destfile="i2pbote-plugin.war" webxml="ant_build/web.xml">
<classes dir="ant_build/classes" includes="i2p/bote/web/** i2p/bote/jsp/** org/apache/jsp/**" />
<fileset dir="WebContent" includes="*.html"/>
<fileset dir="WebContent" includes="*.css"/>
<fileset dir="WebContent/" includes="*.xml"/>
<webinf dir="WebContent/WEB-INF/tlds" includes="*.tld"/>
<zipfileset dir="WebContent/images" prefix="images"/>
<zipfileset dir="WebContent/themes" prefix="themes"/>
<fileset dir="src/main/webapp" includes="*.html"/>
<fileset dir="src/main/webapp/" includes="*.xml"/>
<webinf dir="src/main/webapp/WEB-INF/tlds" includes="*.tld"/>
<zipfileset dir="src/main/webapp/html" prefix="html"/>
<zipfileset dir="src/main/webapp/themes" prefix="themes"/>
</war>
</target>
<macrodef name="includedep">
<attribute name="updater" default="false"/>
<attribute name="dep"/>
<sequential>
<local name="packDep"/>
<local name="removePack"/>
<condition property="packDep" else="false">
<or>
<and>
<istrue value="@{updater}"/>
<istrue value="${@{dep}.includeinupdate}"/>
</and>
<and>
<isfalse value="@{updater}"/>
<isfalse value="${@{dep}.includeinupdate}"/>
</and>
</or>
</condition>
<condition property="removePack" else="false">
<and>
<istrue value="@{updater}"/>
<isfalse value="${@{dep}.includeinupdate}"/>
</and>
</condition>
<ant target="packdep.@{dep}" if:true="${packDep}"/>
<ant target="removepack.@{dep}" if:true="${removePack}"/>
</sequential>
</macrodef>
<target name="packdep.ntruenc">
<packdep dep="ntruenc"/>
</target>
<target name="removepack.ntruenc">
<removepack dep="ntruenc"/>
</target>
<target name="packdep.scrypt">
<packdep dep="scrypt"/>
</target>
<target name="removepack.scrypt">
<removepack dep="scrypt"/>
</target>
<target name="packdep.lzma">
<packdep dep="lzma"/>
</target>
<target name="removepack.lzma">
<removepack dep="lzma"/>
</target>
<target name="packdep.gmss">
<packdep dep="gmss"/>
</target>
<target name="removepack.gmss">
<removepack dep="gmss"/>
</target>
<target name="packdep.jcommon">
<packdep dep="jcommon"/>
</target>
<target name="removepack.jcommon">
<removepack dep="jcommon"/>
</target>
<target name="packdep.jfreechart">
<packdep dep="jfreechart"/>
</target>
<target name="removepack.jfreechart">
<removepack dep="jfreechart"/>
</target>
<target name="packdep.mailapi">
<packdep dep="mailapi"/>
</target>
<target name="removepack.mailapi">
<removepack dep="mailapi"/>
</target>
<target name="packdep.bcprov">
<packdep dep="bcprov">
<arg value="--segment-limit=-1"/>
</packdep>
</target>
<target name="removepack.bcprov">
<removepack dep="bcprov"/>
</target>
<target name="packdep.james">
<apply executable="pack200" failonerror="true" parallel="false" dest="plugin/plugin.tmp/lib/">
<arg value="--no-gzip"/>
<arg value="--effort=9"/>
<arg value="--modification-time=latest"/>
<targetfile/>
<srcfile/>
<fileset refid="imaplibs"/>
<mapper type="glob" from="*.jar" to="*.jar.pack"/>
</apply>
</target>
<target name="removepack.james">
<apply executable="rm" dest="plugin/plugin.tmp/lib/" addsourcefile="false">
<targetfile/>
<fileset refid="imaplibs"/>
<flattenmapper/>
</apply>
<apply executable="rm" dest="plugin/plugin.tmp/lib/" addsourcefile="false">
<targetfile suffix=".pack"/>
<fileset refid="imaplibs"/>
<flattenmapper/>
</apply>
</target>
<target name="packdep.subetha">
<packdep dep="subetha"/>
</target>
<target name="removepack.subetha">
<removepack dep="subetha"/>
</target>
<target name="bundle" depends="compile">
<!-- Update the messages_*.po files.
We need to supply the bat file for windows, and then change the fail property to true -->
<exec executable="sh" osfamily="unix" failifexecutionfails="false" >
<arg value="./bundle-messages.sh" />
<arg value="src/build/scripts/bundle-messages.sh" />
</exec>
<exec executable="sh" osfamily="mac" failifexecutionfails="false" >
<arg value="./bundle-messages.sh" />
<arg value="src/build/scripts/bundle-messages.sh" />
</exec>
<exec executable="sh" osfamily="windows" failifexecutionfails="false" >
<arg value="./bundle-messages.sh" />
<arg value="src/build/scripts/bundle-messages.sh" />
</exec>
</target>
@ -334,12 +580,14 @@
<copy file="i2pbote-plugin.war" tofile="${i2pinstallerplugindir}/console/webapps/i2pbote.war"/>
<copy file="plugin/webapps.config" todir="${i2pinstallerplugindir}/console"/>
<copy file="${lib}/i2pbote.jar" todir="${i2pinstallerplugindir}/lib"/>
<copy file="${lib}/mailapi.jar" todir="${i2pinstallerplugindir}/lib"/>
<copy file="${lib}/bcprov-ecc-jdk16-146.jar" todir="${i2pinstallerplugindir}/lib"/>
<copy file="${lib}/${mailapi.filename}" todir="${i2pinstallerplugindir}/lib"/>
<copy file="${lib}/${bcprov.filename}" todir="${i2pinstallerplugindir}/lib"/>
<copy file="${lib}/ntruenc-1.2.jar" todir="${i2pinstallerplugindir}/lib"/>
<copy file="${lib}/scrypt-1.3.3.jar" todir="${i2pinstallerplugindir}/lib"/>
<copy file="${lib}/scrypt-1.4.0.jar" todir="${i2pinstallerplugindir}/lib"/>
<copy file="${lib}/lzma-9.20.jar" todir="${i2pinstallerplugindir}/lib"/>
<copy file="${lib}/flexi-gmss-1.7p1.jar" todir="${i2pinstallerplugindir}/lib"/>
<copy file="${lib}/jcommon-1.0.23.jar" todir="${i2pinstallerplugindir}/lib"/>
<copy file="${lib}/jfreechart-1.0.19.jar" todir="${i2pinstallerplugindir}/lib"/>
<!-- build the I2P + I2P-Bote install.jar -->
<ant antfile="${installerdir}/i2p.i2p/build.xml" target="installer" inheritAll="false"/>
<copy file="${installerdir}/i2p.i2p/install.jar" todir="${installerresources}"/>
@ -374,15 +622,15 @@
<target name="poupdate" depends="compileantclasses">
<!-- Update the messages_*.po files. -->
<exec executable="sh" osfamily="unix" failonerror="true" >
<arg value="./bundle-messages.sh" />
<arg value="src/build/scripts/bundle-messages.sh" />
<arg value="-p" />
</exec>
<exec executable="sh" osfamily="mac" failonerror="true" >
<arg value="./bundle-messages.sh" />
<arg value="src/build/scripts/bundle-messages.sh" />
<arg value="-p" />
</exec>
<exec executable="sh" osfamily="windows" failifexecutionfails="true" >
<arg value="bundle-messages.sh" />
<arg value="src/build/scripts/bundle-messages.sh" />
<arg value="-p" />
</exec>
</target>
@ -390,7 +638,7 @@
<!-- compiles the Java code in the ant directory -->
<target name="compileantclasses" depends="compile">
<javac
srcdir="./ant"
srcdir="./src/build/java"
debug="true"
deprecation="on"
source="1.6" target="1.6"
@ -404,18 +652,21 @@
<target name="junit" depends="compile">
<available property="junitexists" file="${lib}/${junit.filename}" type="file"/>
<ant target="downloadjunit"/>
<available property="mockitoexists" file="${lib}/${mockito.filename}" type="file"/>
<ant target="downloadmockito"/>
<available property="jmockexists" file="${lib}/${jmock.filename}" type="file"/>
<ant target="downloadjmock"/>
<path id="junitcp">
<pathelement location="${lib}/${junit.filename}"/>
<pathelement location="${lib}/${mockito.filename}"/>
<pathelement path="${jmockcp}"/>
<pathelement location="./ant_build/classes"/>
<path refid="cp"/>
</path>
<javac
srcdir="./test"
srcdir="./src/test/java"
debug="true"
deprecation="on"
source="1.6" target="1.6"
@ -423,9 +674,9 @@
destdir="./ant_build/classes"
classpathref="junitcp"
failonerror="true" />
<copy file="test/i2p/bote/packet/dht/Struwwelpeter.jpg" tofile="ant_build/classes/i2p/bote/packet/dht/Struwwelpeter.jpg"/>
<copy file="src/i2p/bote/crypto/wordlist/words_de.txt" tofile="ant_build/classes/i2p/bote/crypto/wordlist/words_de.txt"/>
<copy file="src/i2p/bote/crypto/wordlist/words_en.txt" tofile="ant_build/classes/i2p/bote/crypto/wordlist/words_en.txt"/>
<copy file="src/test/java/i2p/bote/packet/dht/Struwwelpeter.jpg" tofile="ant_build/classes/i2p/bote/packet/dht/Struwwelpeter.jpg"/>
<copy file="src/main/java/i2p/bote/crypto/wordlist/words_de.txt" tofile="ant_build/classes/i2p/bote/crypto/wordlist/words_de.txt"/>
<copy file="src/main/java/i2p/bote/crypto/wordlist/words_en.txt" tofile="ant_build/classes/i2p/bote/crypto/wordlist/words_en.txt"/>
<echo message="Running JUnit tests..."/>
<junit printsummary="off" failureproperty="failed">
@ -456,6 +707,16 @@
<get src="${junit.url}" verbose="true" dest="${lib}/${junit.filename}"/>
</target>
<target name="downloadmockito" unless="mockitoexists">
<input message="Mockito not found, download now?" validargs="y,n" addproperty="userinput.mockito"/>
<fail message="OK, aborting build." >
<condition>
<equals arg1="${userinput.mockito}" arg2="n"/>
</condition>
</fail>
<get src="${mockito.url}" verbose="true" dest="${lib}/${mockito.filename}"/>
</target>
<target name="downloadjmock" unless="jmockexists">
<input message="jMock not found, download now?" validargs="y,n" addproperty="userinput.jmock"/>
<fail message="OK, aborting build." >
@ -473,11 +734,88 @@
<delete file="${lib}/${jmock.archive}"/>
</target>
<target name="downloadmailapi" unless="mailapiexists">
<input message="JavaMail not found, download now?" validargs="y,n" addproperty="userinput.mailapi"/>
<fail message="OK, aborting build.">
<condition>
<equals arg1="${userinput.mailapi}" arg2="n"/>
</condition>
</fail>
<get src="${mailapi.url}" verbose="true" dest="${lib}/${mailapi.filename}"/>
</target>
<target name="downloadbcprov" unless="bcprovexists">
<input message="BouncyCastle Provider not found, download now?" validargs="y,n" addproperty="userinput.bcprov"/>
<fail message="OK, aborting build.">
<condition>
<equals arg1="${userinput.bcprov}" arg2="n"/>
</condition>
</fail>
<get src="${bcprov.url}" verbose="true" dest="${lib}/${bcprov.filename}"/>
</target>
<target name="downloadjames" unless="jamesexists">
<input message="Apache James not found, download now?" validargs="y,n" addproperty="userinput.junit"/>
<fail message="OK, aborting build.">
<condition>
<equals arg1="${userinput.junit}" arg2="n"/>
</condition>
</fail>
<get src="${james.url}" verbose="true" dest="${lib}/${james.archive}"/>
<unzip src="${lib}/${james.archive}" dest="${lib}">
<patternset>
<include name="**/apache-james-mailbox-api-0.6-20150508.040939-710.jar"/>
<include name="**/apache-james-mailbox-store-0.6-20150508.041003-704.jar"/>
<include name="**/apache-mime4j-core-0.8.0-20150617.024907-738.jar"/>
<include name="**/apache-mime4j-dom-0.8.0-20150617.024927-735.jar"/>
<include name="**/commons-codec-1.7.jar"/>
<include name="**/commons-collections-3.2.1.jar"/>
<include name="**/commons-configuration-1.9.jar"/>
<include name="**/commons-io-2.4.jar"/>
<include name="**/commons-lang-2.6.jar"/>
<include name="**/james-server-filesystem-api-3.0.0-beta5-SNAPSHOT.jar"/>
<include name="**/james-server-lifecycle-api-3.0.0-beta5-SNAPSHOT.jar"/>
<include name="**/james-server-protocols-imap4-3.0.0-beta5-SNAPSHOT.jar"/>
<include name="**/james-server-protocols-library-3.0.0-beta5-SNAPSHOT.jar"/>
<include name="**/james-server-util-3.0.0-beta5-SNAPSHOT.jar"/>
<include name="**/jutf7-1.0.0.jar"/>
<include name="**/log4j-1.2.17.jar"/>
<include name="**/netty-3.3.1.Final.jar"/>
<include name="**/protocols-api-1.6.4-20150617.121129-1080.jar"/>
<include name="**/protocols-imap-1.6.4-20150617.121245-927.jar"/>
<include name="**/protocols-netty-1.6.4-20150617.121137-1044.jar"/>
<include name="**/slf4j-api-1.7.2.jar"/>
<include name="**/slf4j-log4j12-1.7.2.jar"/>
</patternset>
<mapper>
<flattenmapper/>
</mapper>
</unzip>
<delete file="${lib}/${james.archive}"/>
</target>
<target name="downloadsubetha" unless="subethaexists">
<input message="SubEtha SMTP not found, download now?" validargs="y,n" addproperty="userinput.junit"/>
<fail message="OK, aborting build.">
<condition>
<equals arg1="${userinput.junit}" arg2="n"/>
</condition>
</fail>
<get src="${subetha.url}" verbose="true" dest="${lib}/${subetha.archive}"/>
<unzip src="${lib}/${subetha.archive}" dest="${lib}">
<patternset includes="**/${subetha.filename}"/>
<mapper>
<flattenmapper/>
</mapper>
</unzip>
<delete file="${lib}/${subetha.archive}"/>
</target>
<!-- Write the app version into ${version} -->
<!-- Depends on compile b/c it gets the app version from I2PBote.class -->
<target name="getversion" depends="compile">
<javac
srcdir="./ant"
srcdir="./src/build/java"
debug="true"
deprecation="on"
source="1.6" target="1.6"
@ -499,18 +837,14 @@
<target name="src" depends="getversion">
<property name="subdir" value="i2pbote-${version}-src"/>
<zip destfile="src.zip">
<zipfileset dir="src" prefix="${subdir}/src"/>
<zipfileset dir="WebContent" prefix="${subdir}/WebContent" followsymlinks="false"/>
<zipfileset dir="test" prefix="${subdir}/test"/>
<zipfileset dir="ant" prefix="${subdir}/ant"/>
<zipfileset dir="src" prefix="${subdir}/src" followsymlinks="false"/>
<zipfileset dir="doc" prefix="${subdir}/doc"/>
<zipfileset dir="plugin" prefix="${subdir}/plugin">
<exclude name="plugin.tmp/**"/>
</zipfileset>
<zipfileset file="build.xml" prefix="${subdir}"/>
<zipfileset file="locale/messages_de.po" prefix="${subdir}/locale"/>
<zipfileset file="bundle-messages.sh" prefix="${subdir}"/>
<zipfileset file="jsp2po.sh" prefix="${subdir}"/>
<zipfileset file="src/build/scripts/bundle-messages.sh" prefix="${subdir}"/>
<zipfileset file="history.txt" prefix="${subdir}"/>
<zipfileset file="license.txt" prefix="${subdir}"/>
</zip>
@ -535,7 +869,7 @@
<property name="pkglistdir" value="ant_build/package_lists"/>
<mkdir dir="${pkglistdir}" />
<echo message="Downloading package lists"/>
<mkdir dir="${pkglistdir}/jdk"/>
<java classname="net.i2p.util.EepGet" classpath="${i2plib}/i2p.jar">
<arg value="-o"/>
@ -581,6 +915,7 @@
<target name="clean">
<delete dir="ant_build" />
<delete file="${lib}/i2pbote.jar" />
<delete file="i2pbote.war" />
<delete file="i2pbote-plugin.war" />
<delete dir="plugin/plugin.tmp" />
@ -590,4 +925,11 @@
<delete file="i2pinstall.exe" />
<delete dir="javadoc" />
</target>
<target name="distclean" depends="clean">
<delete>
<fileset refid="imaplibs"/>
</delete>
<delete file="${lib}/${subetha.filename}" />
</target>
</project>

View File

@ -122,13 +122,13 @@ The Kademlia implementation used by I2P-Bote differs from standard Kademlia in s
* No caching of DHT items because they are only retrieved once and then deleted
* I2P-Bote uses sibling lists (s-buckets) as suggested in the S/Kademlia paper
There are two types of data that is stored in the DHT: Email Packets and Index Packets. A third data type
will be added for the address directory when it is implemented.
There are three types of data that is stored in the DHT: Email Packets, Index Packets, and Contacts.
Index packets contain the DHT keys of one or more email packets. The DHT key of an index packet is the
SHA-256 hash of the Email Destination the email packets are destined for.
To check for new email for a given Email Destination, I2P-Bote first queries the DHT for index packets for that
Email Destination, then queries the DHT for all email packet keys in the index packets. When a complete set of
email packets has been received, the email is reconstructed and placed in the inbox.
TODO Contacts
To delete an email packet, or an entry in an index packet, the delete request must contain the correct
verification code (the delete verification hash). The verification code is the SHA-256 hash of another block of
@ -239,8 +239,6 @@ Strings in packets are UTF8 encoded.
| COMP | 1 byte | Compression type for TEXT
| TLEN | 2 bytes | Length of the TEXT field, max 2000
| TEXT | byte[] | User defined text in UTF8
| SLEN | 2 bytes | Length of SIG
| SIG | byte[] | A signature over the [TYPE, ..., TEXT] fields by DEST
--------------------+-------+------------+------------------------------------------------------------------
3.2. Communication Packets
@ -352,7 +350,7 @@ Strings in packets are UTF8 encoded.
| DTYP | 1 byte | Type of data to retrieve:
| | | 'I' = Index Packet
| | | 'E' = Email Packet
| | | 'M' = Directory Entry
| | | 'C' = Directory Entry
| KEY | 32 bytes | DHT key to look up
--------------------+-------+------------+------------------------------------------------------------------
Deletion Query | | | A request to a peer to return a Deletion Info Packet for a given
@ -568,22 +566,32 @@ Here is a simplified diagram of how a Relay Return Packet is sent from one hop t
6.1. Identities file
Stores all email identities the local user has created. One line per entry.
Format:
<base64 key><tab><public name>[<tab><description>][<tab><email address>]
Stores all email identities the local user has created. The file uses the
Java Properties format, and can be read into / written out from a Java
Properties object.
The following property keys are currently stored and recognized:
identity#.publicName - The public name of the identity, included in emails.
identity#.key - Base64 of the identity keys.
identity#.salt - Salt used to generate a fingerprint.
identity#.description - Description of the identity, only displayed locally.
identity#.picture - Base64 of byte[] containing picture data
identity#.text - Text associated with the identity.
identity#.published - Has the identity been published to the public addressbook?
(# is an integer index)
The base64 key contains two public keys (encryption+signing) and two private
keys.
The identities file can optionally contain a line that contains the string
"Default", a space, and an Email Destination (i.e. two public keys). If the
The identities file can optionally contain the property key "default", with
its value set to an Email Destination (i.e. two public keys). If the
Email Destination matches one of the identities, that identity is used as
the default.
6.2. Included .jar files and third-party source code
bcprov-ecc-jdk16-146.jar A stripped down version of the BouncyCastle library,
containing only the classes needed for ECC.
mailapi.jar Part of JavaMail
bcprov-jdk15on-152.jar The BouncyCastle library and SecurityProvider.
mailapi-1.5.4.jar Part of JavaMail 1.5.4
lzma-9.20.jar An LZMA implementation from http://www.7-zip.org/sdk.html
ntruenc-1.2.jar An NTRU implementation from http://sf.net/projects/ntru/
(only the NTRUEncrypt part, not NTRUSign)
@ -593,7 +601,7 @@ Here is a simplified diagram of how a Relay Return Packet is sent from one hop t
The patch consists of a modified de.flexiprovider.core.CoreRegistry
and de.flexiprovider.api.Registry and its purpose is to
reduce dependencies on classes not related to GMSS.
scrypt-1.3.3.jar An scrypt implementation from https://github.com/wg/scrypt/
scrypt-1.4.0.jar An scrypt implementation from https://github.com/wg/scrypt/
7. Cryptography
@ -627,10 +635,16 @@ Here is a simplified diagram of how a Relay Return Packet is sent from one hop t
can use the same key derivation parameters. This makes decryption much faster because
the key only needs to be derived once per session.
7.3. Fingerprints For Directory Entries
8. Setting Up a Development Environment
TODO
H = scrypt(name, dest, zuf.wert); die letzten 8 Binärstellen von H müssen 0 sein
13*7+22+18 = 131
8.1. Eclipse
8. Development
8.1. Setting up Eclipse
Rough steps, may not be complete:
@ -647,7 +661,7 @@ Here is a simplified diagram of how a Relay Return Packet is sent from one hop t
* Comment out all lines in built-in-peers.txt and disable seedless so you get a closed network
* Start and stop all servers, then go to Debug Configurations (or Run Configurations)
and add the following to Arguments -> VM arumgents:
-Di2p.dir.config="/path/to/<work_dir>/" -Di2p.dir.app="/path/to/<work_dir>"
-Di2p.dir.config="/path/to/<work_dir>/i2pbote/" -Di2p.dir.app="/path/to/<work_dir>/i2pbote/"
where <work_dir> is the name you gave that work dir. Repeat for the other servers.
* Edit built-in-peers.txt and add the I2P destination from the first test server
* Create a file named logger.config in each work dir with the following contents:
@ -656,6 +670,12 @@ Here is a simplified diagram of how a Relay Return Packet is sent from one hop t
* Start two or more servers, go to http://localhost:<port>/i2p.i2p-bote/, and click "connect".
After a minute, it should say "connected" and you should see the other server(s) on network.jsp.
8.2. Transifex
To update translations from Transifex, run "tx pull". On Debian and its derivatives, tx can be
installed via "sudo apt-get install transifex-client". After installation, run "tx init" in
the project directory.
9. Glossary of Terms
@ -679,7 +699,7 @@ Email Destination
Email Address
Email Addresses in I2P-Bote are shortcuts for Email Destinations.
Email Address <--> Email Destination mappings are stored in two places: the local address book and the
distributed address directory (the latter not being implemented yet).
distributed address directory.
Email Identity
An Email Identity is an Email Destination plus a name you want to be known as when you use that identity.

View File

@ -1,8 +1,52 @@
I2P-Bote Version History
------------------------
0.4.1 (Released on Sep 12, 2015)
* Fixed bugs:
o ConcurrentModificationException errors in logs
o User guide and FAQ not loading translations
0.4 (Released on Aug 21, 2015)
* Fixed bugs:
o Email checking would get stuck if no new mail was found
o "Last checked" time was inconsistent for manual checks
o Anonymous emails would never send
* Removed build number from version
* Skipped 0.3.* series
o 0.3.1 is less than 0.3-b195; would need to go to 0.3.196
0.3 (Released on Aug 15, 2015)
* New default theme based on Material design
* New features:
o Exclude individual identities from global email checking
o Manual per-identity email checking
o Import and export identities
* Strip prefixes, spaces and newlines from email destinations (to better
handle destinations pasted from different sources). Supported prefixes:
o mailto:
o bote:
o i2pbote:
* Translations for user guide and FAQ
* Use I2P XSSFilter on inputs
* Bundle BouncyCastle 1.51 crypto provider
* In-app update notification removed
* IMAP temporarily disabled due to bug
* Bug fixes
0.2.10 (Released on Jul 23, 2014)
* Vanity destinations
* Security fix related to ElGamal email destinations
* IMAP fixes
* "After merging, IndexPacket is too big..." error fixed
* Numerous fixes and enhancements by str4d
0.2.9 (Released on Feb 7, 2014)
* Experimental SMTP and IMAP support
* UI and IMAP improvements by str4d
* Misc. UI improvements
0.2.8 (Released on Mar 8, 2013)
* Fixes and enhancements to the address directory
* Fixes and enhancements to the address directory
0.2.7 (Released on Feb 13, 2013)
* Delivery confirmations

BIN
lib/jcommon-1.0.23.jar Normal file

Binary file not shown.

BIN
lib/jfreechart-1.0.19.jar Normal file

Binary file not shown.

View File

@ -2,5 +2,9 @@ LICENSES
--------
This software is licensed under the GPL version 3 (see licenses/GPLv3.txt),
except for bcprov-ecc-jdk16-146.jar which is licensed under the
Bouncy Castle License (see licenses/BouncyCastle.txt).
except for:
- bcprov-jdk15on-152.jar which is licensed under the Bouncy Castle License
(see licenses/BouncyCastle.txt).
- nl.jteam.tls.StrongTls which is licensed under the Apache License, Version
2.0 (see licenses/LICENSE-Apache2.0.txt).

View File

@ -0,0 +1,202 @@
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.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1317
locale/messages_fi.po Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1352
locale/messages_id.po Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1343
locale/messages_ja.po Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1339
locale/messages_pt_BR.po Normal file

File diff suppressed because it is too large Load Diff

1356
locale/messages_ro.po Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1353
locale/messages_sk.po Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -92,12 +92,12 @@
<java-data xmlns="http://www.netbeans.org/ns/freeform-project-java/1">
<compilation-unit>
<package-root>test</package-root>
<classpath mode="compile">../i2p/core/java/build/i2p.jar:../i2p/apps/jetty/jettylib/org.mortbay.jetty.jar:../i2p/apps/jetty/jettylib/jasper-compiler.jar:../i2p/apps/jetty/jettylib/jasper-runtime.jar:../i2p/apps/jetty/jettylib/javax.servlet.jar:../i2p/apps/jetty/jettylib/commons-logging.jar:../i2p/apps/jetty/jettylib/commons-el.jar:../i2p/apps/susidns/src/WEB-INF/lib/jstl.jar:../i2p/apps/susidns/src/WEB-INF/lib/standard.jar:WebContent/WEB-INF/lib/mailapi.jar:WebContent/WEB-INF/lib/bcprov-ecc-jdk16-146.jar:ant_build/classes:/usr/local/netbeans-6.5/platform9/modules/ext/junit-4.5.jar:../i2p/router/java/build/router.jar:WebContent/WEB-INF/lib/commons-fileupload-1.2.1.jar:WebContent/WEB-INF/lib/commons-io-1.4.jar</classpath>
<classpath mode="compile">../i2p/core/java/build/i2p.jar:../i2p/apps/jetty/jettylib/org.mortbay.jetty.jar:../i2p/apps/jetty/jettylib/jasper-compiler.jar:../i2p/apps/jetty/jettylib/jasper-runtime.jar:../i2p/apps/jetty/jettylib/javax.servlet.jar:../i2p/apps/jetty/jettylib/commons-logging.jar:../i2p/apps/jetty/jettylib/commons-el.jar:../i2p/apps/susidns/src/WEB-INF/lib/jstl.jar:../i2p/apps/susidns/src/WEB-INF/lib/standard.jar:WebContent/WEB-INF/lib/mailapi.jar:WebContent/WEB-INF/lib/bcprov-jdk15on-152.jar:ant_build/classes:/usr/local/netbeans-6.5/platform9/modules/ext/junit-4.5.jar:../i2p/router/java/build/router.jar:WebContent/WEB-INF/lib/commons-fileupload-1.2.1.jar:WebContent/WEB-INF/lib/commons-io-1.4.jar</classpath>
<source-level>1.5</source-level>
</compilation-unit>
<compilation-unit>
<package-root>src</package-root>
<classpath mode="compile">../i2p/core/java/build/i2p.jar:../i2p/apps/jetty/jettylib/org.mortbay.jetty.jar:../i2p/apps/jetty/jettylib/jasper-compiler.jar:../i2p/apps/jetty/jettylib/jasper-runtime.jar:../i2p/apps/jetty/jettylib/javax.servlet.jar:../i2p/apps/jetty/jettylib/commons-logging.jar:../i2p/apps/jetty/jettylib/commons-el.jar:../i2p/apps/susidns/src/WEB-INF/lib/jstl.jar:../i2p/apps/susidns/src/WEB-INF/lib/standard.jar:WebContent/WEB-INF/lib/mailapi.jar:WebContent/WEB-INF/lib/bcprov-ecc-jdk16-146.jar:ant_build/classes:../i2p/apps/streaming/java/build/streaming.jar:../i2p/apps/ministreaming/java/build/mstreaming.jar:../i2p/apps/routerconsole/java/build/routerconsole.jar:../i2p/router/java/build/router.jar:WebContent/WEB-INF/lib/commons-fileupload-1.2.1.jar:WebContent/WEB-INF/lib/commons-io-1.4.jar</classpath>
<classpath mode="compile">../i2p/core/java/build/i2p.jar:../i2p/apps/jetty/jettylib/org.mortbay.jetty.jar:../i2p/apps/jetty/jettylib/jasper-compiler.jar:../i2p/apps/jetty/jettylib/jasper-runtime.jar:../i2p/apps/jetty/jettylib/javax.servlet.jar:../i2p/apps/jetty/jettylib/commons-logging.jar:../i2p/apps/jetty/jettylib/commons-el.jar:../i2p/apps/susidns/src/WEB-INF/lib/jstl.jar:../i2p/apps/susidns/src/WEB-INF/lib/standard.jar:WebContent/WEB-INF/lib/mailapi.jar:WebContent/WEB-INF/lib/bcprov-jdk15on-152.jar:ant_build/classes:../i2p/apps/streaming/java/build/streaming.jar:../i2p/apps/ministreaming/java/build/mstreaming.jar:../i2p/apps/routerconsole/java/build/routerconsole.jar:../i2p/router/java/build/router.jar:WebContent/WEB-INF/lib/commons-fileupload-1.2.1.jar:WebContent/WEB-INF/lib/commons-io-1.4.jar</classpath>
<built-to>ant_build/classes</built-to>
<source-level>1.5</source-level>
</compilation-unit>

View File

@ -1,5 +1,5 @@
name=i2pbote
signer=HungryHobo@mail.i2p
signer=str4d@mail.i2p
consoleLinkName=SecureMail
consoleLinkName_de=Sichere.Mail
consoleLinkName_nl=Beveiligde Mail
@ -23,8 +23,10 @@ consoleLinkTooltip_sv=Decentraliserad säker e-post
consoleLinkTooltip_zh=安全分布式电子邮件
consoleLinkTooltip_ar=بريد الكتروني الآمن و الغير متمركز
consoleLinkURL=/i2pbote/index.jsp
websiteURL=http://i2pbote.i2p/
updateURL=http://i2pbote.i2p/i2pbote-update.xpi2p
console-icon=/themes/material/icon.png
websiteURL=http://bote.i2p/
updateURL=http://bote.i2p/i2pbote-update.xpi2p
updateURL.su3=http://bote.i2p/i2pbote-update.su3
description=Decentralized secure email
description_de=Dezentrale, sichere Mailanwendung
description_nl=Gedecentraliseerde beveiligde email
@ -38,4 +40,5 @@ description_zh=安全分布式电子邮件
description_ar=بريد الكتروني الآمن و الغير متمركز
license=GPL V3
min-java-version=1.6
author=HungryHobo@mail.i2p
min-i2p-version=0.9.18
author=str4d@mail.i2p

View File

@ -1 +1 @@
webapps.i2pbote.classpath=$I2P/lib/jstl.jar,$I2P/lib/standard.jar,$PLUGIN/lib/i2pbote.jar,$PLUGIN/lib/mailapi.jar,$PLUGIN/lib/bcprov-ecc-jdk16-146.jar,$PLUGIN/lib/flexi-gmss-1.7p1.jar,$PLUGIN/lib/ntruenc-1.2.jar,$PLUGIN/lib/scrypt-1.3.3.jar,$PLUGIN/lib/lzma-9.20.jar
webapps.i2pbote.classpath=$I2P/lib/jstl.jar,$I2P/lib/standard.jar,$PLUGIN/lib/i2pbote.jar,$PLUGIN/lib/mailapi-1.5.4.jar,$PLUGIN/lib/bcprov-jdk15on-152.jar,$PLUGIN/lib/flexi-gmss-1.7p1.jar,$PLUGIN/lib/ntruenc-1.2.jar,$PLUGIN/lib/scrypt-1.4.0.jar,$PLUGIN/lib/lzma-9.20.jar,$PLUGIN/lib/apache-james-mailbox-api-0.6-20150508.040939-710.jar,$PLUGIN/lib/apache-james-mailbox-store-0.6-20150508.041003-704.jar,$PLUGIN/lib/apache-mime4j-core-0.8.0-20150617.024907-738.jar,$PLUGIN/lib/commons-codec-1.7.jar,$PLUGIN/lib/commons-collections-3.2.1.jar,$PLUGIN/lib/commons-configuration-1.9.jar,$PLUGIN/lib/commons-io-2.4.jar,$PLUGIN/lib/commons-lang-2.6.jar,$PLUGIN/lib/james-server-filesystem-api-3.0.0-beta5-SNAPSHOT.jar,$PLUGIN/lib/james-server-lifecycle-api-3.0.0-beta5-SNAPSHOT.jar,$PLUGIN/lib/james-server-protocols-imap4-3.0.0-beta5-SNAPSHOT.jar,$PLUGIN/lib/james-server-protocols-library-3.0.0-beta5-SNAPSHOT.jar,$PLUGIN/lib/james-server-util-3.0.0-beta5-SNAPSHOT.jar,$PLUGIN/lib/jcommon-1.0.23.jar,$PLUGIN/lib/jfreechart-1.0.19.jar,$PLUGIN/lib/jutf7-1.0.0.jar,$PLUGIN/lib/log4j-1.2.17.jar,$PLUGIN/lib/netty-3.3.1.Final.jar,$PLUGIN/lib/protocols-api-1.6.4-20150617.121129-1080.jar,$PLUGIN/lib/protocols-imap-1.6.4-20150617.121245-927.jar,$PLUGIN/lib/protocols-netty-1.6.4-20150617.121137-1044.jar,$PLUGIN/lib/slf4j-api-1.7.2.jar,$PLUGIN/lib/slf4j-log4j12-1.7.2.jar,$PLUGIN/lib/subethasmtp-3.1.7.jar

View File

@ -32,8 +32,8 @@ echo setting the environment variable LG2={LangCode}
echo will limit .po file update to the language specified by {LangCode}.
# add ../java/ so the refs will work in the po file
JPATHS="src"
JSPPATHS="WebContent"
JPATHS="src/main/java"
JSPPATHS="src/main/webapp"
for i in locale/messages_*.po
do
# get language
@ -80,7 +80,7 @@ do
fi
# extract strings from jsp files
$JAVA -cp ant_build/classes i2p.bote.ant.JspStrings WebContent >> ${i}t
$JAVA -cp ant_build/classes:$I2P/lib/i2p.jar i2p.bote.ant.JspStrings $JSPPATHS >> ${i}t
if [ $? -ne 0 ]
then
echo 'Warning - JspStrings failed, not updating translations'

View File

@ -1,74 +0,0 @@
/**
* Copyright (C) 2009 HungryHobo@mail.i2p
*
* The GPG fingerprint for HungryHobo@mail.i2p is:
* 6DD3 EAA2 9990 29BC 4AD2 7486 1E2C 7B61 76DC DC12
*
* This file is part of I2P-Bote.
* I2P-Bote is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* I2P-Bote is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with I2P-Bote. If not, see <http://www.gnu.org/licenses/>.
*/
package i2p.bote.email;
import i2p.bote.addressbook.AddressBook;
import i2p.bote.fileencryption.PasswordException;
import i2p.bote.packet.dht.Contact;
import java.io.IOException;
import java.security.GeneralSecurityException;
/**
* This class is used for adding/replacing names in email addresses with
* local names (address book entries and email identities).
*/
public class AddressDisplayFilter {
private Identities identities;
private AddressBook addressBook;
public AddressDisplayFilter(Identities identities, AddressBook addressBook) {
this.identities = identities;
this.addressBook = addressBook;
}
/**
* Looks up the name associated with a Base64-encoded Email Destination
* in the address book and the local identities, and returns a string
* that contains the name and the Base64-encoded destination.<br/>
* If <code>address</code> already contains a name, it is replaced with
* the one from the address book or identities.<br/>
* If no name is found in the address book or the identities, or if
* <code>address</code> does not contain a valid Email Destination,
* <code>address</code> is returned.
* @param address A Base64-encoded Email Destination, and optionally a name
* @throws PasswordException
* @throws GeneralSecurityException
* @throws IOException
*/
public String getNameAndDestination(String address) throws PasswordException, IOException, GeneralSecurityException {
String base64dest = EmailDestination.extractBase64Dest(address);
if (base64dest != null) {
// try the address book
Contact contact = addressBook.get(base64dest);
if (contact != null)
return contact.getName() + " <" + contact.getBase64Dest() + ">";
// if no address book entry, try the email identities
EmailIdentity identity = identities.get(base64dest);
if (identity != null)
return identity.getPublicName() + " <" + identity.toBase64() + ">";
}
return address;
}
}

View File

@ -1,213 +0,0 @@
/**
* Copyright (C) 2009 HungryHobo@mail.i2p
*
* The GPG fingerprint for HungryHobo@mail.i2p is:
* 6DD3 EAA2 9990 29BC 4AD2 7486 1E2C 7B61 76DC DC12
*
* This file is part of I2P-Bote.
* I2P-Bote is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* I2P-Bote is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with I2P-Bote. If not, see <http://www.gnu.org/licenses/>.
*/
package i2p.bote.email;
import i2p.bote.Util;
import i2p.bote.crypto.CryptoFactory;
import i2p.bote.crypto.CryptoImplementation;
import i2p.bote.crypto.PrivateKeyPair;
import i2p.bote.crypto.PublicKeyPair;
import java.nio.charset.Charset;
import java.security.GeneralSecurityException;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.PrivateKey;
import net.i2p.crypto.SHA256Generator;
import net.i2p.data.Hash;
import com.lambdaworks.codec.Base64;
public class EmailIdentity extends EmailDestination {
private final static Charset UTF8 = Charset.forName("UTF-8");
private PrivateKey privateEncryptionKey;
private PrivateKey privateSigningKey;
private String publicName;
private String description; // optional
private String emailAddress; // optional
private byte[] picture;
private String text;
private Fingerprint fingerprint;
private boolean published;
private boolean isDefault;
/**
* Creates a random <code>EmailIdentity</code>.
* @param cryptoImpl
* @throws GeneralSecurityException
*/
public EmailIdentity(CryptoImplementation cryptoImpl) throws GeneralSecurityException {
super();
this.cryptoImpl = cryptoImpl;
KeyPair encryptionKeys = cryptoImpl.generateEncryptionKeyPair();
KeyPair signingKeys = cryptoImpl.generateSigningKeyPair();
publicEncryptionKey = encryptionKeys.getPublic();
privateEncryptionKey = encryptionKeys.getPrivate();
publicSigningKey = signingKeys.getPublic();
privateSigningKey = signingKeys.getPrivate();
}
/**
* Creates a <code>EmailIdentity</code> from a Base64-encoded string.
* The format can be any format supported by one of the {@link CryptoImplementation}s;
* the length of the string must match {@link CryptoImplementation#getBase64CompleteKeySetLength()}.
* @param base64Key
* @throws GeneralSecurityException
*/
public EmailIdentity(String base64Key) throws GeneralSecurityException {
// find the crypto implementation for this key length
for (CryptoImplementation cryptoImpl: CryptoFactory.getInstances()) {
int base64Length = cryptoImpl.getBase64CompleteKeySetLength(); // length of an email identity with this CryptoImplementation
if (base64Key.length() == base64Length) {
this.cryptoImpl = cryptoImpl;
break;
}
}
if (cryptoImpl == null)
throw new InvalidKeyException("Not a valid Email Identity, no CryptoImplementation (out of " + CryptoFactory.getInstances().size() + ") matches length " + base64Key.length() + ": <" + base64Key + ">");
PublicKeyPair publicKeys = cryptoImpl.createPublicKeyPair(base64Key);
String base64PrivateKeys = base64Key.substring(cryptoImpl.getBase64PublicKeyPairLength()); // the two private keys start after the two public keys
PrivateKeyPair privateKeys = cryptoImpl.createPrivateKeyPair(base64PrivateKeys);
publicEncryptionKey = publicKeys.encryptionKey;
privateEncryptionKey = privateKeys.encryptionKey;
publicSigningKey = publicKeys.signingKey;
privateSigningKey = privateKeys.signingKey;
}
public PrivateKey getPrivateEncryptionKey() {
return privateEncryptionKey;
}
public PrivateKey getPrivateSigningKey() {
return privateSigningKey;
}
public void setPublicName(String publicName) {
this.publicName = publicName;
}
public String getPublicName() {
return publicName;
}
public void setDescription(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
public void setEmailAddress(String emailAddress) {
this.emailAddress = emailAddress;
}
public String getEmailAddress() {
return emailAddress;
}
public void setPublished(boolean published) {
this.published = published;
}
public boolean isPublished() {
return published;
}
public void setPicture(byte[] picture) {
this.picture = picture;
}
public byte[] getPicture() {
return picture;
}
public String getPictureBase64() {
if (picture == null)
return null;
return new String(Base64.encode(picture));
}
/** @see Util#getPictureType(byte[]) */
public String getPictureType() {
return Util.getPictureType(picture);
}
public void setText(String text) {
this.text = text;
}
public String getText() {
return text;
}
public void generateFingerprint() throws GeneralSecurityException {
fingerprint = Fingerprint.generate(this);
}
public void setFingerprint(Fingerprint fingerprint) {
this.fingerprint = fingerprint;
}
public Fingerprint getFingerprint() throws GeneralSecurityException {
return fingerprint;
}
public static Hash calculateHash(String name) {
name = name.trim();
if (name.endsWith("@bote.i2p"))
name = name.substring(0, name.length()-"@bote.i2p".length());
byte[] nameBytes = name.toLowerCase().getBytes(UTF8);
return SHA256Generator.getInstance().calculateHash(nameBytes);
}
public void setDefault(boolean isDefault) {
this.isDefault = isDefault;
}
public boolean isDefault() {
return isDefault;
}
/**
* Returns the two key pairs (public + private) as one Base64-encoded string.
* @throws GeneralSecurityException
*/
public String getFullKey() throws GeneralSecurityException {
PublicKeyPair publicKeys = new PublicKeyPair(publicEncryptionKey, publicSigningKey);
PrivateKeyPair privateKeys = new PrivateKeyPair(privateEncryptionKey, privateSigningKey);
String pubKeys = cryptoImpl.toBase64(publicKeys);
String privKeys = cryptoImpl.toBase64(privateKeys);
return pubKeys + privKeys;
}
@Override
public String toString() {
return getKey() + " address=<" + getEmailAddress() + "> identity name=<" + getDescription() + "> visible name=<" + getPublicName() + ">";
}
}

View File

@ -1,5 +0,0 @@
# Each line in this file should be a 516-byte I2P destination key
# in Base64 format. Lines beginning with # are ignored.
AHZwTj~5kmXod-2jFj1RamSFMBijtEnp9x3FWrF19uJQQga~rH4OaAtqdrHBeKfSBwugWEQMI8~shhBpk3H~fgQEd24RntmItdFzCsdeKz~0WnYqvhZo-ZryXk6J08wTPX9hX8BWuJSTgQyJo7WvDEqxx2AxQUIDyWVPld7VdfrpNEFWTQPNo0YxQWqSlnhSZr~hIVEV6hRsRgAP89Il8tnRa0f2YqZI7Ac2p8btVTkXMExVfLqZ2Y6J71K53oJ1mXZCISGUVAJhRWhdl~QKT8x-V5~5iSLoGG0514E4KOGc1ViKhl4YvhfCVXezm-oVDT8e9QTgy1pYjk9U88ng7hg~vjlCx8g2F3zTbZMaMZch4K50j7cRHFxvWA47EiEw~AtlEWhzTyQY2HMfQE-Hj7CJISdoaPk3ehvpkSDPdLWDSeQ~7rSYujWBAH~KI1DViRElS-1oJ3rPLqNTA2IwywbbaCs0LnAX9NrTnwIx4X6~kr7Re8DLVw5Gn-vjsrYjAAAA
CYnzmb1axrzpDXEX9haV7qBT-jGxFmLmkV913DgPqgJ1lVcSfpIrTe4ETMsRRjd2JMvGJxBYznENH8oTlitVptNAe8HjXYxjPqCRkHeh3QCk9nZALTWxjGy90DUHytIytPwRYqIZlLneiePhVFgV-HXOne~Bsv-mT5zrfDIDNhkJlmyXq5vLcvTkqp-eDEMr6iC4njCNKjzHDxsTvwwecYSmzFDY2f0SMZhrmL3qKSofMVPwpEVwkBX7LF50TSOfPvIEVgX7uPKI~avIOrShksSdJ0ksDQkw5Q66tOp-yrgxh--FnQYnblfLMBhI5UyWuifV3HqGqctjjHfW2mEOVpIoarjgbdmN9knThRBlgC8gs7AffoYuKs~GbIsE4PpnJI2rS3skBfPoNcmBtUF2bfQZ6gb3zk8NH7alXWMciF3wXyLka2FBuQKQQz4fUuraVzQu0COncv0hpmV5CIO7HWTs8pdem6~r0NydoRF3wrGj8xDeySTVJfmDfXCKhi0GAAAA
aIQVk2lM0o0Y3TNMuayovLl0GSR8FJsc59ntiYI-ycuijZUuW0FJJEKc3pUAL8TF9VqcZHtPNHK0Hy5~S-7XuwYjUpjPcTRFH~tiqbH2lXtF~zpJvjrJoIzVR2ZaIbd3-6cXkQw11gRLkODdRh314HdtnJNEdNr2D-YNxqH9HHTPKOj7H0jlRuIkuzlyBzRm3h0udsW6-BS70Iv2Pmo1KNK7a8PEZMiwig8pYylLXyc-kYVVoiBwCKaz0xe8GaFWXv-MLLdHtJ9KBBQMuYuow-dVlvNIAku0hFhuYgjDYs9beO7yLkFxQQ3-ai2r58YfGoemx3CRX3yDwkYykzMuYTyQjJU0lyUBqc4K7dvbiHDK1ts2WWiI8LNPfk-Z0jZqEsuIp36bRPd9TM6H-~8CVHu1XJEviuGKzuj-ak1KFGm-FGrale-zw3OnarPTWL8rWKki3OvAlKZK6V~Qh0PcH-pZCZYBfxbTekX8w3zVgNR1PCQ2BSNelChmTdmhcLyKAAAA

View File

@ -1,121 +0,0 @@
/**
* Copyright (C) 2009 HungryHobo@mail.i2p
*
* The GPG fingerprint for HungryHobo@mail.i2p is:
* 6DD3 EAA2 9990 29BC 4AD2 7486 1E2C 7B61 76DC DC12
*
* This file is part of I2P-Bote.
* I2P-Bote is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* I2P-Bote is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with I2P-Bote. If not, see <http://www.gnu.org/licenses/>.
*/
package i2p.bote.service;
import i2p.bote.Configuration;
import i2p.bote.network.NetworkStatusSource;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import net.i2p.I2PAppContext;
import net.i2p.crypto.TrustedUpdate;
import net.i2p.data.DataHelper;
import net.i2p.util.I2PAppThread;
import net.i2p.util.Log;
import net.i2p.util.PartialEepGet;
/**
* Periodically checks for an updated version of I2P-Bote.<br/>
* It may be worth moving this code into the router so other plugins
* can use it.
*/
public class UpdateChecker extends I2PAppThread {
private static final int XPI2P_HEADER_LENGTH = 56;
private static final String PLUGIN_CONFIG_PATH = "plugins/i2pbote/plugin.config"; // relative to the I2P config dir
private Log log = new Log(UpdateChecker.class);
private NetworkStatusSource networkStatusSource;
private Configuration configuration;
private boolean updateAvailable;
/**
* @param configuration
*/
public UpdateChecker(NetworkStatusSource networkStatusSource, Configuration configuration) {
super("UpdateCheckr");
this.networkStatusSource = networkStatusSource;
this.configuration = configuration;
}
private void checkForUpdate() {
String eeproxyHost = configuration.getEeproxyHost();
int eeproxyPort = configuration.getEeproxyPort();
String updateUrl = configuration.getUpdateUrl();
ByteArrayOutputStream response = new ByteArrayOutputStream();
I2PAppContext context = I2PAppContext.getGlobalContext();
PartialEepGet eepGet = new PartialEepGet(context, eeproxyHost, eeproxyPort, response, updateUrl, XPI2P_HEADER_LENGTH);
boolean success = eepGet.fetch();
if (!success) {
log.error("Can't check update URL: " + updateUrl);
return;
}
try {
String currentVersion = getCurrentVersion(context);
byte[] responseBytes = response.toByteArray();
String newVersion = TrustedUpdate.getVersionString(new ByteArrayInputStream(responseBytes));
if (TrustedUpdate.needsUpdate(currentVersion, newVersion))
updateAvailable = true;
}
catch (IOException e) {
log.error("Can't compare plugin versions: " + e.getLocalizedMessage());
}
}
/** See <code>i2p.i2p/apps/routerconsole/java/src/net/i2p/router/web/PluginStarter.java</code> */
private String getCurrentVersion(I2PAppContext context) throws IOException {
File cfgFile = new File(context.getConfigDir(), PLUGIN_CONFIG_PATH);
Properties rv = new Properties();
DataHelper.loadProps(rv, cfgFile);
return rv.getProperty("version");
}
public synchronized boolean isUpdateAvailable() {
return updateAvailable;
}
@Override
public void run() {
while (!Thread.interrupted()) {
try {
if (!networkStatusSource.isConnected()) // if not connected, use a shorter wait interval
TimeUnit.MINUTES.sleep(1);
else {
checkForUpdate();
TimeUnit.MINUTES.sleep(configuration.getUpdateCheckInterval());
}
} catch (InterruptedException e) {
break;
} catch (RuntimeException e) { // catch unexpected exceptions to keep the thread running
log.error("Exception caught in UpdateChecker loop", e);
}
}
log.debug("UpdateChecker thread exiting.");
}
}

View File

@ -22,6 +22,7 @@
package i2p.bote;
import static i2p.bote.Util._;
import i2p.bote.email.EmailIdentity.IdentityConfig;
import i2p.bote.packet.dht.Contact;
import java.io.File;
@ -33,12 +34,15 @@ import java.util.List;
import java.util.Properties;
import net.i2p.I2PAppContext;
import net.i2p.crypto.KeyStoreUtil;
import net.i2p.data.DataHelper;
import net.i2p.util.Log;
import net.i2p.util.SecureFile;
import net.i2p.util.SystemVersion;
public class Configuration {
public class Configuration implements IdentityConfig {
public static final String KEY_DERIVATION_PARAMETERS_FILE = "derivparams"; // name of the KDF parameter cache file, relative to I2P_BOTE_SUBDIR
private static final String I2P_BOTE_SUBDIR = "i2pbote"; // relative to the I2P app dir
private static final String CONFIG_FILE_NAME = "i2pbote.config";
private static final String DEST_KEY_FILE_NAME = "local_dest.key";
@ -48,6 +52,8 @@ public class Configuration {
private static final String ADDRESS_BOOK_FILE_NAME = "addressBook";
private static final String MESSAGE_ID_CACHE_FILE = "msgidcache.txt";
private static final String PASSWORD_FILE = "password";
private static final String SSL_KEYSTORE_FILE = "i2p.bote.ssl.keystore.jks"; // relative to I2P_BOTE_SUBDIR
private static final String SSL_KEY_ALIAS = "botessl";
private static final String OUTBOX_DIR = "outbox"; // relative to I2P_BOTE_SUBDIR
private static final String RELAY_PKT_SUBDIR = "relay_pkt"; // relative to I2P_BOTE_SUBDIR
private static final String INCOMPLETE_SUBDIR = "incomplete"; // relative to I2P_BOTE_SUBDIR
@ -59,18 +65,25 @@ public class Configuration {
private static final String TRASH_FOLDER_DIR = "trash"; // relative to I2P_BOTE_SUBDIR
private static final String MIGRATION_VERSION_FILE = "migratedVersion"; // relative to I2P_BOTE_SUBDIR
private static final List<Theme> BUILT_IN_THEMES = Arrays.asList(new Theme[] { // theme IDs correspond to a theme directory in the .war
new Theme("lblue", _("lblue")),
new Theme("vanilla", _("vanilla"))
new Theme("material", _("Material")),
new Theme("lblue", _("Light Blue")),
new Theme("vanilla", _("Vanilla"))
});
private static final String THEME_SUBDIR = "themes"; // relative to I2P_BOTE_SUBDIR
// Parameter names in the config file
private static final String PARAMETER_I2CP_DOMAIN_SOCKET_ENABLED = "i2cpDomainSocketEnabled";
private static final String PARAMETER_STORAGE_SPACE_INBOX = "storageSpaceInbox";
private static final String PARAMETER_STORAGE_SPACE_RELAY = "storageSpaceRelay";
private static final String PARAMETER_STORAGE_TIME = "storageTime";
private static final String PARAMETER_HASHCASH_STRENGTH = "hashCashStrength";
private static final String PARAMETER_SMTP_PORT = "smtpPort";
private static final String PARAMETER_POP3_PORT = "pop3Port";
private static final String PARAMETER_SMTP_ADDRESS = "smtpAddress";
private static final String PARAMETER_SMTP_ENABLED = "smtpEnabled";
private static final String PARAMETER_IMAP_PORT = "imapPort";
private static final String PARAMETER_IMAP_ADDRESS = "imapAddress";
private static final String PARAMETER_IMAP_ENABLED = "imapEnabled";
private static final String PARAMETER_SSL_KEYSTORE_PASSWORD = "sslKeystorePassword";
private static final String PARAMETER_MAX_CONCURRENT_IDENTITIES_CHECK_MAIL = "maxConcurIdCheckMail";
private static final String PARAMETER_AUTO_MAIL_CHECK = "autoMailCheckEnabled";
private static final String PARAMETER_DELIVERY_CHECK = "deliveryCheckEnabled";
@ -93,14 +106,19 @@ public class Configuration {
private static final String PARAMETER_UPDATE_URL = "updateUrl";
private static final String PARAMETER_UPDATE_CHECK_INTERVAL = "updateCheckInterval";
private static final String PARAMETER_THEME = "theme";
// Defaults for each parameter
private static final boolean DEFAULT_I2CP_DOMAIN_SOCKET_ENABLED = false;
private static final int DEFAULT_STORAGE_SPACE_INBOX = 1024 * 1024 * 1024;
private static final int DEFAULT_STORAGE_SPACE_RELAY = 100 * 1024 * 1024;
private static final int DEFAULT_STORAGE_TIME = 31; // in days
private static final int DEFAULT_HASHCASH_STRENGTH = 10;
private static final int DEFAULT_SMTP_PORT = 7661;
private static final int DEFAULT_POP3_PORT = 7662;
private static final String DEFAULT_SMTP_ADDRESS = "localhost";
private static final boolean DEFAULT_SMTP_ENABLED = false;
private static final int DEFAULT_IMAP_PORT = 7662;
private static final String DEFAULT_IMAP_ADDRESS = "localhost";
private static final boolean DEFAULT_IMAP_ENABLED = false;
private static final int DEFAULT_MAX_CONCURRENT_IDENTITIES_CHECK_MAIL = 10;
private static final boolean DEFAULT_AUTO_MAIL_CHECK = true;
private static final int DEFAULT_MAIL_CHECK_INTERVAL = 30; // in minutes
@ -122,13 +140,13 @@ public class Configuration {
private static final int DEFAULT_EEPROXY_PORT = 4444;
private static final String DEFAULT_UPDATE_URL = "http://tjgidoycrw6s3guetge3kvrvynppqjmvqsosmtbmgqasa6vmsf6a.b32.i2p/i2pbote-update.xpi2p";
private static final int DEFAULT_UPDATE_CHECK_INTERVAL = 60; // in minutes
private static final String DEFAULT_THEME = "lblue";
private static final String DEFAULT_THEME = "material";
private Log log = new Log(Configuration.class);
private Properties properties;
private File i2pBoteDir;
private File configFile;
/**
* Reads configuration settings from the <code>I2P_BOTE_SUBDIR</code> subdirectory under
* the I2P application directory. The I2P application directory can be changed via the
@ -140,18 +158,18 @@ public class Configuration {
*/
public Configuration() {
properties = new Properties();
// get the I2PBote directory and make sure it exists
i2pBoteDir = getI2PBoteDirectory();
if (!i2pBoteDir.exists() && !i2pBoteDir.mkdirs())
log.error("Cannot create directory: <" + i2pBoteDir.getAbsolutePath() + ">");
log.error("Cannot create directory: <" + i2pBoteDir.getAbsolutePath() + ">");
// read the configuration file
configFile = new File(i2pBoteDir, CONFIG_FILE_NAME);
boolean configurationLoaded = false;
if (configFile.exists()) {
log.info("Loading config file <" + configFile.getAbsolutePath() + ">");
try {
DataHelper.loadProps(properties, configFile);
configurationLoaded = true;
@ -161,32 +179,92 @@ public class Configuration {
}
if (!configurationLoaded)
log.info("Can't read configuration file <" + configFile.getAbsolutePath() + ">, using default settings.");
// Create SSL key if necessary
if (!SystemVersion.isAndroid()) {
File ks = getSSLKeyStoreFile();
if (!ks.exists())
createKeyStore(ks);
}
}
private boolean createKeyStore(File ks) {
// make a random 48 character password (30 * 8 / 5)
String keyStorePassword = KeyStoreUtil.randomString();
// and one for the cname
String cname = KeyStoreUtil.randomString() + ".ssl.bote.i2p";
boolean success = KeyStoreUtil.createKeys(
ks, keyStorePassword, SSL_KEY_ALIAS, cname, "I2P-Bote",
3652, "RSA", 2048, keyStorePassword);
if (success) {
success = ks.exists();
if (success) {
properties.setProperty(PARAMETER_SSL_KEYSTORE_PASSWORD, keyStorePassword);
save();
}
}
if (success) {
log.logAlways(Log.INFO, "Created self-signed certificate for " + cname + " in keystore: " + ks.getAbsolutePath() + "\n" +
"The certificate name was generated randomly, and is not associated with your " +
"IP address, host name, router identity, or destination keys.");
} else {
log.error("Failed to create I2P-Bote SSL keystore.\n" +
"This is for the Sun/Oracle keytool, others may be incompatible.\n" +
"If you create the keystore manually, you must add " + PARAMETER_SSL_KEYSTORE_PASSWORD +
" to " + (new File(i2pBoteDir, CONFIG_FILE_NAME)).getAbsolutePath() + "\n" +
"You must create the keystore using the same password for the keystore and the key.");
}
return success;
}
/**
* @param enabled ignored if not on Android.
* @since 0.2.10
*/
public void setI2CPDomainSocketEnabled(boolean enabled) {
if (SystemVersion.isAndroid())
properties.setProperty(
PARAMETER_I2CP_DOMAIN_SOCKET_ENABLED,
String.valueOf(enabled));
}
/**
* @return false if not on Android.
* @since 0.2.10
*/
public boolean isI2CPDomainSocketEnabled() {
return SystemVersion.isAndroid() ?
getBooleanParameter(
PARAMETER_I2CP_DOMAIN_SOCKET_ENABLED,
DEFAULT_I2CP_DOMAIN_SOCKET_ENABLED) :
false;
}
public File getDestinationKeyFile() {
return new File(i2pBoteDir, DEST_KEY_FILE_NAME);
}
public File getDhtPeerFile() {
return new File(i2pBoteDir, DHT_PEER_FILE_NAME);
}
public File getRelayPeerFile() {
return new File(i2pBoteDir, RELAY_PEER_FILE_NAME);
}
public File getIdentitiesFile() {
return new File(i2pBoteDir, IDENTITIES_FILE_NAME);
}
public File getAddressBookFile() {
return new File(i2pBoteDir, ADDRESS_BOOK_FILE_NAME);
}
public File getMessageIdCacheFile() {
return new File(i2pBoteDir, MESSAGE_ID_CACHE_FILE);
}
/**
* The file returned by this method does not contain the user's password,
* but a known string that is encrypted with the password. The purpose
@ -196,7 +274,7 @@ public class Configuration {
public File getPasswordFile() {
return new File(i2pBoteDir, PASSWORD_FILE);
}
/**
* Returns the file that caches the parameters needed for generating a
* file encryption key from a password.
@ -204,35 +282,43 @@ public class Configuration {
public File getKeyDerivationParametersFile() {
return new File(i2pBoteDir, KEY_DERIVATION_PARAMETERS_FILE);
}
/**
* @return the keystore file containing the SSL server key.
* @since 0.2.10
*/
public File getSSLKeyStoreFile() {
return new File(i2pBoteDir, SSL_KEYSTORE_FILE);
}
public File getOutboxDir() {
return new File(i2pBoteDir, OUTBOX_DIR);
}
public File getRelayPacketDir() {
return new File(i2pBoteDir, RELAY_PKT_SUBDIR);
}
public File getSentFolderDir() {
return new File(i2pBoteDir, SENT_FOLDER_DIR);
}
public File getTrashFolderDir() {
return new File(i2pBoteDir, TRASH_FOLDER_DIR);
}
public File getInboxDir() {
return new File(i2pBoteDir, INBOX_SUBDIR);
}
public File getIncompleteDir() {
return new File(i2pBoteDir, INCOMPLETE_SUBDIR);
}
public File getEmailDhtStorageDir() {
return new File(i2pBoteDir, EMAIL_DHT_SUBDIR);
}
public File getIndexPacketDhtStorageDir() {
return new File(i2pBoteDir, INDEX_PACKET_DHT_SUBDIR);
}
@ -241,22 +327,21 @@ public class Configuration {
public File getDirectoryEntryDhtStorageDir() {
return new File(i2pBoteDir, DIRECTORY_ENTRY_DHT_SUBDIR);
}
private static File getI2PBoteDirectory() {
// the parent directory of the I2PBote directory ($HOME or the value of the i2p.dir.app property)
File i2pAppDir = I2PAppContext.getGlobalContext().getAppDir();
return new File(i2pAppDir, I2P_BOTE_SUBDIR);
}
/**
* Saves the configuration to a file.
*/
public void save() {
log.debug("Saving config file <" + configFile.getAbsolutePath() + ">");
try {
DataHelper.storeProps(properties, configFile);
Util.makePrivate(configFile);
DataHelper.storeProps(properties, new SecureFile(configFile.getAbsolutePath()));
} catch (IOException e) {
log.error("Cannot save configuration to file <" + configFile.getAbsolutePath() + ">", e);
}
@ -268,14 +353,14 @@ public class Configuration {
public int getStorageSpaceInbox() {
return getIntParameter(PARAMETER_STORAGE_SPACE_INBOX, DEFAULT_STORAGE_SPACE_INBOX);
}
/**
* Returns the maximum size (in bytes) all messages stored for relaying can take up.
*/
public int getStorageSpaceRelay() {
return getIntParameter(PARAMETER_STORAGE_SPACE_RELAY, DEFAULT_STORAGE_SPACE_RELAY);
}
/**
* Returns the time (in milliseconds) after which an email is deleted from the outbox if it cannot be sent or relayed.
*/
@ -286,34 +371,84 @@ public class Configuration {
public int getHashCashStrength() {
return getIntParameter(PARAMETER_HASHCASH_STRENGTH, DEFAULT_HASHCASH_STRENGTH);
}
public void setSmtpPort(int port) {
properties.setProperty(PARAMETER_SMTP_PORT, String.valueOf(port));
}
public int getSmtpPort() {
return getIntParameter(PARAMETER_SMTP_PORT, DEFAULT_SMTP_PORT);
}
/** Returns the host name the SMTP server listens on. */
public String getSmtpAddress() {
return properties.getProperty(PARAMETER_SMTP_ADDRESS, DEFAULT_SMTP_ADDRESS);
}
public void setSmtpEnabled(boolean enabled) {
properties.setProperty(PARAMETER_SMTP_ENABLED, String.valueOf(enabled));
}
public boolean isSmtpEnabled() {
return getBooleanParameter(PARAMETER_SMTP_ENABLED, DEFAULT_SMTP_ENABLED);
}
public void setImapPort(int port) {
properties.setProperty(PARAMETER_IMAP_PORT, String.valueOf(port));
}
public int getImapPort() {
return getIntParameter(PARAMETER_IMAP_PORT, DEFAULT_IMAP_PORT);
}
/** Returns the host name the IMAP server listens on. */
public String getImapAddress() {
return properties.getProperty(PARAMETER_IMAP_ADDRESS, DEFAULT_IMAP_ADDRESS);
}
public void setImapEnabled(boolean enabled) {
properties.setProperty(PARAMETER_IMAP_ENABLED, String.valueOf(enabled));
}
public boolean isImapEnabled() {
return getBooleanParameter(PARAMETER_IMAP_ENABLED, DEFAULT_IMAP_ENABLED);
}
/**
* @return the password for the SSL keystore.
* @since 0.2.10
*/
public String getSSLKeyStorePassword() {
return properties.getProperty(PARAMETER_SSL_KEYSTORE_PASSWORD);
}
/**
* Returns the maximum number of email identities to retrieve new emails for at a time.
*/
public int getMaxConcurIdCheckMail() {
return getIntParameter(PARAMETER_MAX_CONCURRENT_IDENTITIES_CHECK_MAIL, DEFAULT_MAX_CONCURRENT_IDENTITIES_CHECK_MAIL);
}
public void setAutoMailCheckEnabled(boolean enabled) {
properties.setProperty(PARAMETER_AUTO_MAIL_CHECK, String.valueOf(enabled));
}
public boolean isAutoMailCheckEnabled() {
return getBooleanParameter(PARAMETER_AUTO_MAIL_CHECK, DEFAULT_AUTO_MAIL_CHECK);
}
public void setDeliveryCheckEnabled(boolean enabled) {
properties.setProperty(PARAMETER_DELIVERY_CHECK, String.valueOf(enabled));
}
public boolean isDeliveryCheckEnabled() {
return getBooleanParameter(PARAMETER_DELIVERY_CHECK, DEFAULT_DELIVERY_CHECK);
}
public void setMailCheckInterval(int minutes) {
properties.setProperty(PARAMETER_MAIL_CHECK_INTERVAL, String.valueOf(minutes));
}
/**
* Returns the number of minutes the application should wait before
* checking for mail again. This setting only has an effect if
@ -327,7 +462,7 @@ public class Configuration {
public void setOutboxCheckInterval(int minutes) {
properties.setProperty(PARAMETER_OUTBOX_CHECK_INTERVAL, String.valueOf(minutes));
}
/**
* Returns the wait time, in minutes, before processing the outbox folder again.
* @see i2p.bote.service.OutboxProcessor
@ -339,7 +474,7 @@ public class Configuration {
public void getDeliveryCheckInterval(int minutes) {
properties.setProperty(PARAMETER_DELIVERY_CHECK_INTERVAL, String.valueOf(minutes));
}
/**
* Returns the wait time, in minutes, between checking the delivery status of sent emails.
* @see i2p.bote.service.DeliveryChecker
@ -351,14 +486,14 @@ public class Configuration {
public void setRelaySendPause(int minutes) {
properties.setProperty(PARAMETER_RELAY_SEND_PAUSE, String.valueOf(minutes));
}
/**
* Returns the number of minutes to wait before processing the relay packet folder again.
*/
public int getRelaySendPause() {
return getIntParameter(PARAMETER_RELAY_SEND_PAUSE, DEFAULT_RELAY_SEND_PAUSE);
}
/**
* Controls whether strings that are added to outgoing email, like "Re:" or "Fwd:",
* are translated or not.<br/>
@ -370,7 +505,7 @@ public class Configuration {
public void setHideLocale(boolean hideLocale) {
properties.setProperty(PARAMETER_HIDE_LOCALE, String.valueOf(hideLocale));
}
public boolean getHideLocale() {
return getBooleanParameter(PARAMETER_HIDE_LOCALE, DEFAULT_HIDE_LOCALE);
}
@ -382,48 +517,48 @@ public class Configuration {
public void setIncludeSentTime(boolean includeSentTime) {
properties.setProperty(PARAMETER_INCLUDE_SENT_TIME, String.valueOf(includeSentTime));
}
public boolean getIncludeSentTime() {
return getBooleanParameter(PARAMETER_INCLUDE_SENT_TIME, DEFAULT_INCLUDE_SENT_TIME);
}
public int getMessageIdCacheSize() {
return getIntParameter(PARAMETER_MESSAGE_ID_CACHE_SIZE, DEFAULT_MESSAGE_ID_CACHE_SIZE);
}
/**
* Returns the number of relay chains that should be used per Relay Request.
*/
public int getRelayRedundancy() {
return getIntParameter(PARAMETER_RELAY_REDUNDANCY, DEFAULT_RELAY_REDUNDANCY);
}
public void setRelayMinDelay(int minDelay) {
properties.setProperty(PARAMETER_RELAY_MIN_DELAY, String.valueOf(minDelay));
}
/**
* Returns the minimum amount of time in minutes that a Relay Request is delayed.
*/
public int getRelayMinDelay() {
return getIntParameter(PARAMETER_RELAY_MIN_DELAY, DEFAULT_RELAY_MIN_DELAY);
}
public void setRelayMaxDelay(int maxDelay) {
properties.setProperty(PARAMETER_RELAY_MAX_DELAY, String.valueOf(maxDelay));
}
/**
* Returns the maximum amount of time in minutes that a Relay Request is delayed.
*/
public int getRelayMaxDelay() {
return getIntParameter(PARAMETER_RELAY_MAX_DELAY, DEFAULT_RELAY_MAX_DELAY);
}
public void setNumStoreHops(int numHops) {
properties.setProperty(PARAMETER_NUM_STORE_HOPS, String.valueOf(numHops));
}
/**
* Returns the number of relays that should be used when sending a DHT store request.
* @return A non-negative number
@ -431,15 +566,15 @@ public class Configuration {
public int getNumStoreHops() {
return getIntParameter(PARAMETER_NUM_STORE_HOPS, DEFAULT_NUM_STORE_HOPS);
}
public void setGatewayDestination(String destination) {
properties.setProperty(PARAMETER_GATEWAY_DESTINATION, destination);
}
public String getGatewayDestination() {
return properties.getProperty(PARAMETER_GATEWAY_DESTINATION, DEFAULT_GATEWAY_DESTINATION);
}
public void setGatewayEnabled(boolean enable) {
properties.setProperty(PARAMETER_GATEWAY_ENABLED, String.valueOf(enable));
}
@ -451,29 +586,29 @@ public class Configuration {
public void setPasswordCacheDuration(int duration) {
properties.setProperty(PARAMETER_PASSWORD_CACHE_DURATION, String.valueOf(duration));
}
/**
* Returns the number of minutes the password is kept in memory
*/
public int getPasswordCacheDuration() {
return getIntParameter(PARAMETER_PASSWORD_CACHE_DURATION, DEFAULT_PASSWORD_CACHE_DURATION);
}
public String getEeproxyHost() {
return properties.getProperty(PARAMETER_EEPROXY_HOST, DEFAULT_EEPROXY_HOST);
}
public int getEeproxyPort() {
return getIntParameter(PARAMETER_EEPROXY_PORT, DEFAULT_EEPROXY_PORT);
}
/**
* Returns an HTTP URL pointing to the .xpi2p update file.
*/
public String getUpdateUrl() {
return properties.getProperty(PARAMETER_UPDATE_URL, DEFAULT_UPDATE_URL);
}
/**
* Returns the number of minutes to wait after checking for a new plugin version.
*/
@ -484,14 +619,14 @@ public class Configuration {
public void setThemeUrl(String url) {
properties.setProperty(PARAMETER_THEME, url);
}
/**
* Returns the name of the current UI theme.
*/
public String getTheme() {
return properties.getProperty(PARAMETER_THEME, DEFAULT_THEME);
}
/**
* Returns a list of all available UI themes.
*/
@ -501,21 +636,21 @@ public class Configuration {
themes.addAll(getExternalThemes());
return themes;
}
/**
* Returns only the UI themes that are included in the application.
*/
public List<Theme> getBuiltInThemes() {
return BUILT_IN_THEMES;
}
/**
* Returns the directory where the application looks for additional UI themes.
*/
public File getExternalThemeDir() {
return new File(i2pBoteDir, THEME_SUBDIR);
}
private List<Theme> getExternalThemes() {
File[] dirs = new File(i2pBoteDir, THEME_SUBDIR).listFiles(new FileFilter() {
@Override
@ -523,7 +658,7 @@ public class Configuration {
return pathname.isDirectory();
}
});
List<Theme> themes = new ArrayList<Theme>();
if (dirs != null)
for (File dir: dirs) {
@ -533,7 +668,7 @@ public class Configuration {
}
return themes;
}
/**
* Returns the File that contains the version the I2P-Bote data directory was last
* successfully migrated to.
@ -541,45 +676,35 @@ public class Configuration {
public File getMigrationVersionFile() {
return new File(i2pBoteDir, MIGRATION_VERSION_FILE);
}
private boolean getBooleanParameter(String parameterName, boolean defaultValue) {
String stringValue = properties.getProperty(parameterName);
if ("true".equalsIgnoreCase(stringValue) || "yes".equalsIgnoreCase(stringValue) || "on".equalsIgnoreCase(stringValue) || "1".equals(stringValue))
return true;
else if ("false".equalsIgnoreCase(stringValue) || "no".equalsIgnoreCase(stringValue) || "off".equalsIgnoreCase(stringValue) || "0".equals(stringValue))
return false;
else if (stringValue == null)
return defaultValue;
else {
log.warn("<" + stringValue + "> is not a legal value for the boolean parameter <" + parameterName + ">");
try {
return Util.getBooleanParameter(properties, parameterName, defaultValue);
} catch (IllegalArgumentException e) {
log.warn("getBooleanParameter failed, using default", e);
return defaultValue;
}
}
private int getIntParameter(String parameterName, int defaultValue) {
String stringValue = properties.getProperty(parameterName);
if (stringValue == null)
try {
return Util.getIntParameter(properties, parameterName, defaultValue);
} catch (NumberFormatException e) {
log.warn("getIntParameter failed, using default", e);
return defaultValue;
else
try {
return new Integer(stringValue);
}
catch (NumberFormatException e) {
log.warn("Can't convert value <" + stringValue + "> for parameter <" + parameterName + "> to int, using default.");
return defaultValue;
}
}
}
/** Simple class that represents a UI theme */
public static class Theme {
private String id;
private String displayName;
private Theme(String id, String displayName) {
this.id = id;
this.displayName = displayName;
}
public String getId() {
return id;
}

View File

@ -24,6 +24,7 @@ package i2p.bote;
import static i2p.bote.Util._;
import i2p.bote.addressbook.AddressBook;
import i2p.bote.crypto.wordlist.WordListAnchor;
import i2p.bote.debug.DebugSupport;
import i2p.bote.email.Email;
import i2p.bote.email.EmailIdentity;
import i2p.bote.email.Identities;
@ -32,15 +33,19 @@ import i2p.bote.fileencryption.FileEncryptionUtil;
import i2p.bote.fileencryption.PasswordCache;
import i2p.bote.fileencryption.PasswordCacheListener;
import i2p.bote.fileencryption.PasswordException;
import i2p.bote.fileencryption.PasswordVerifier;
import i2p.bote.folder.DirectoryEntryFolder;
import i2p.bote.folder.EmailFolder;
import i2p.bote.folder.EmailFolderManager;
import i2p.bote.folder.EmailPacketFolder;
import i2p.bote.folder.IncompleteEmailFolder;
import i2p.bote.folder.IndexPacketFolder;
import i2p.bote.folder.MessageIdCache;
import i2p.bote.folder.NewEmailListener;
import i2p.bote.folder.Outbox;
import i2p.bote.folder.RelayPacketFolder;
import i2p.bote.folder.TrashFolder;
import i2p.bote.imap.ImapService;
import i2p.bote.migration.Migrator;
import i2p.bote.network.BanList;
import i2p.bote.network.BannedPeer;
@ -50,6 +55,7 @@ import i2p.bote.network.DhtResults;
import i2p.bote.network.I2PPacketDispatcher;
import i2p.bote.network.I2PSendQueue;
import i2p.bote.network.NetworkStatus;
import i2p.bote.network.NetworkStatusListener;
import i2p.bote.network.NetworkStatusSource;
import i2p.bote.network.RelayPacketHandler;
import i2p.bote.network.RelayPeer;
@ -63,32 +69,37 @@ import i2p.bote.service.EmailChecker;
import i2p.bote.service.ExpirationThread;
import i2p.bote.service.OutboxListener;
import i2p.bote.service.OutboxProcessor;
import i2p.bote.service.POP3Service;
import i2p.bote.service.RelayPacketSender;
import i2p.bote.service.RelayPeerManager;
import i2p.bote.service.SMTPService;
import i2p.bote.service.UpdateChecker;
import i2p.bote.service.seedless.SeedlessInitializer;
import i2p.bote.smtp.SmtpService;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.lang.Thread.State;
import java.net.URISyntaxException;
import java.net.UnknownHostException;
import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import javax.mail.MessagingException;
@ -107,13 +118,17 @@ import net.i2p.data.Destination;
import net.i2p.data.Hash;
import net.i2p.util.I2PAppThread;
import net.i2p.util.Log;
import net.i2p.util.SecureFile;
import net.i2p.util.SecureFileOutputStream;
import org.apache.commons.configuration.ConfigurationException;
/**
* This is the core class of the application. It is implemented as a singleton.
*/
public class I2PBote implements NetworkStatusSource {
public class I2PBote implements NetworkStatusSource, EmailFolderManager, MailSender, PasswordVerifier {
public static final int PROTOCOL_VERSION = 4;
private static final String APP_VERSION = "0.2.8";
private static final String APP_VERSION = "0.4.1";
private static final int STARTUP_DELAY = 3; // the number of minutes to wait before connecting to I2P (this gives the router time to get ready)
private static volatile I2PBote instance;
@ -135,16 +150,18 @@ public class I2PBote implements NetworkStatusSource {
private DirectoryEntryFolder directoryDhtFolder; // stores entries for the distributed address directory
private WordListAnchor wordLists;
private Collection<I2PAppThread> backgroundThreads;
private SMTPService smtpService;
private POP3Service pop3Service;
private SmtpService smtpService;
private ImapService imapService;
private OutboxProcessor outboxProcessor; // reads emails stored in the outbox and sends them
private EmailChecker emailChecker;
private DeliveryChecker deliveryChecker;
private UpdateChecker updateChecker;
private KademliaDHT dht;
private RelayPeerManager peerManager;
private PasswordCache passwordCache;
private Future<Void> passwordChangeResult;
private ConnectTask connectTask;
private DebugSupport debugSupport;
private Collection<NetworkStatusListener> networkStatusListeners;
/**
* Constructs a new instance of <code>I2PBote</code> and initializes
@ -186,7 +203,11 @@ public class I2PBote implements NetworkStatusSource {
initializeFolderAccess(passwordCache);
initializeExternalThemeDir();
debugSupport = new DebugSupport(configuration, passwordCache);
wordLists = new WordListAnchor();
networkStatusListeners = new ArrayList<NetworkStatusListener>();
}
/**
@ -217,11 +238,13 @@ public class I2PBote implements NetworkStatusSource {
* Sets up a {@link I2PSession}, using the I2P destination stored on disk or creating a new I2P
* destination if no key file exists.
*/
private void initializeSession() {
private void initializeSession() throws I2PSessionException {
Properties sessionProperties = new Properties();
// set tunnel names
sessionProperties.setProperty("inbound.nickname", "I2P-Bote");
sessionProperties.setProperty("outbound.nickname", "I2P-Bote");
if (configuration.isI2CPDomainSocketEnabled())
sessionProperties.setProperty("i2cp.domainSocket", "true");
// According to sponge, muxed depends on gzip, so leave gzip enabled
// read the local destination key from the key file if it exists
@ -233,12 +256,13 @@ public class I2PBote implements NetworkStatusSource {
fileReader.read(destKeyBuffer);
byte[] localDestinationKey = Base64.decode(new String(destKeyBuffer));
ByteArrayInputStream inputStream = new ByteArrayInputStream(localDestinationKey);
socketManager = I2PSocketManagerFactory.createManager(inputStream, sessionProperties);
socketManager = I2PSocketManagerFactory.createDisconnectedManager(inputStream, null, 0, sessionProperties);
}
catch (IOException e) {
log.debug("Destination key file doesn't exist or isn't readable." + e);
}
finally {
} catch (I2PSessionException e) {
// Won't happen, inputStream != null
} finally {
if (fileReader != null)
try {
fileReader.close();
@ -255,12 +279,10 @@ public class I2PBote implements NetworkStatusSource {
ByteArrayOutputStream arrayStream = new ByteArrayOutputStream();
i2pClient.createDestination(arrayStream);
byte[] localDestinationKey = arrayStream.toByteArray();
ByteArrayInputStream inputStream = new ByteArrayInputStream(localDestinationKey);
socketManager = I2PSocketManagerFactory.createManager(inputStream, sessionProperties);
if (socketManager == null) // null indicates an error
log.error("Error creating I2PSocketManagerFactory");
socketManager = I2PSocketManagerFactory.createDisconnectedManager(inputStream, null, 0, sessionProperties);
saveLocalDestinationKeys(destinationKeyFile, localDestinationKey);
} catch (I2PException e) {
log.error("Error creating local destination key.", e);
@ -268,8 +290,11 @@ public class I2PBote implements NetworkStatusSource {
log.error("Error writing local destination key to file.", e);
}
}
i2pSession = socketManager.getSession();
// Throws I2PSessionException if the connection fails
i2pSession.connect();
Destination localDestination = i2pSession.getMyDestination();
log.info("Local destination key (base64): " + localDestination.toBase64());
log.info("Local destination hash (base64): " + localDestination.calculateHash().toBase64());
@ -284,10 +309,6 @@ public class I2PBote implements NetworkStatusSource {
i2pSession.addMuxedSessionListener(dispatcher, I2PSession.PROTO_DATAGRAM, I2PSession.PORT_ANY);
backgroundThreads.add(passwordCache);
/* smtpService = new SMTPService();
backgroundThreads.add(smtpService);
pop3Service = new POP3Service();
backgroundThreads.add(pop3Service);*/
I2PSendQueue sendQueue = new I2PSendQueue(i2pSession, dispatcher);
backgroundThreads.add(sendQueue);
RelayPacketSender relayPacketSender = new RelayPacketSender(sendQueue, relayPacketFolder, configuration); // reads packets stored in the relayPacketFolder and sends them
@ -340,9 +361,6 @@ public class I2PBote implements NetworkStatusSource {
deliveryChecker = new DeliveryChecker(dht, sentFolder, configuration, this);
backgroundThreads.add(deliveryChecker);
updateChecker = new UpdateChecker(this, configuration);
backgroundThreads.add(updateChecker);
}
/**
@ -353,6 +371,7 @@ public class I2PBote implements NetworkStatusSource {
* @throws IOException
*/
private void saveLocalDestinationKeys(File keyFile, byte[] localDestinationArray) throws DataFormatException, IOException {
keyFile = new SecureFile(keyFile.getAbsolutePath());
if (keyFile.exists()) {
File oldKeyFile = new File(keyFile.getPath() + "_backup");
if (!keyFile.renameTo(oldKeyFile))
@ -362,14 +381,13 @@ public class I2PBote implements NetworkStatusSource {
if (!keyFile.createNewFile())
log.error("Cannot create destination key file: <" + keyFile.getAbsolutePath() + ">");
FileWriter fileWriter = new FileWriter(keyFile);
BufferedWriter fileWriter = new BufferedWriter(new OutputStreamWriter(new SecureFileOutputStream(keyFile)));
try {
fileWriter.write(Base64.encode(localDestinationArray));
}
finally {
fileWriter.close();
}
Util.makePrivate(keyFile);
}
/**
@ -382,6 +400,12 @@ public class I2PBote implements NetworkStatusSource {
connectTask = new ConnectTask();
backgroundThreads.add(connectTask);
connectTask.start();
// TODO Fix log4j loading so IMAP can start
if (false && configuration.isImapEnabled())
startImap();
if (configuration.isSmtpEnabled())
startSmtp();
}
public void shutDown() {
@ -395,6 +419,9 @@ public class I2PBote implements NetworkStatusSource {
}
if (socketManager != null)
socketManager.destroySocketManager();
connectTask = null;
networkStatusChanged();
}
public static I2PBote getInstance() {
@ -478,12 +505,12 @@ public class I2PBote implements NetworkStatusSource {
return i2pSession.getMyDestination();
}
public void sendEmail(Email email) throws Exception {
public void sendEmail(Email email) throws MessagingException, PasswordException, IOException, GeneralSecurityException, DataFormatException {
email.checkAddresses();
// sign email unless sender is anonymous
if (!email.isAnonymous()) {
String sender = email.getSender().toString();
String sender = email.getOneFromAddress();
EmailIdentity senderIdentity = identities.extractIdentity(sender);
if (senderIdentity == null)
throw new MessagingException(_("No identity matches the sender/from field: " + sender));
@ -500,14 +527,10 @@ public class I2PBote implements NetworkStatusSource {
emailChecker.checkForMail();
}
/** Returns <code>true</code> if I2P-Bote can be updated to a newer version */
public boolean isUpdateAvailable() {
if (updateChecker == null)
return false;
else
return updateChecker.isUpdateAvailable();
public synchronized void checkForMail(String key) throws PasswordException, IOException, GeneralSecurityException {
emailChecker.checkForMail(key);
}
/**
* @see EmailChecker#isCheckingForMail()
*/
@ -518,6 +541,16 @@ public class I2PBote implements NetworkStatusSource {
return emailChecker.isCheckingForMail();
}
/**
* @see EmailChecker#isCheckingForMail(EmailIdentity)
*/
public synchronized boolean isCheckingForMail(EmailIdentity identity) {
if (emailChecker == null)
return false;
else
return emailChecker.isCheckingForMail(identity);
}
/**
* @see EmailChecker#getLastMailCheckTime()
*/
@ -540,6 +573,56 @@ public class I2PBote implements NetworkStatusSource {
return emailChecker.newMailReceived();
}
public void setImapEnabled(boolean enabled) {
configuration.setImapEnabled(enabled);
if (imapService==null || !imapService.isStarted()) {
// TODO Fix log4j loading so IMAP can start
if (false && enabled)
startImap();
}
else if (imapService!=null && imapService.isStarted() && !enabled)
stopImap();
}
private void startImap() {
try {
imapService = new ImapService(configuration, this, this);
if (!imapService.start())
log.error("IMAP service failed to start.");
} catch (ConfigurationException e) {
log.error("IMAP service failed to start.", e);
}
}
private void stopImap() {
if (imapService!=null && !imapService.stop())
log.error("IMAP service failed to stop");
}
public void setSmtpEnabled(boolean enabled) {
configuration.setSmtpEnabled(enabled);
if (smtpService==null || !smtpService.isRunning()) {
if (enabled)
startSmtp();
}
else if (smtpService!=null && smtpService.isRunning() && !enabled)
stopSmtp();
}
private void startSmtp() {
try {
smtpService = new SmtpService(configuration, this, this);
smtpService.start();
} catch (UnknownHostException e) {
log.error("SMTP service failed to start.");
}
}
private void stopSmtp() {
if (smtpService != null)
smtpService.stop();
}
public EmailFolder getInbox() {
return inbox;
}
@ -555,9 +638,55 @@ public class I2PBote implements NetworkStatusSource {
public EmailFolder getTrashFolder() {
return trashFolder;
}
public int getNumIncompleteEmails() {
return incompleteEmailFolder.getNumIncompleteEmails();
}
public void addNewEmailListener(NewEmailListener newEmailListener) {
incompleteEmailFolder.addNewEmailListener(newEmailListener);
}
public void removeNewEmailListener(NewEmailListener newEmailListener) {
incompleteEmailFolder.removeNewEmailListener(newEmailListener);
}
public boolean moveToTrash(EmailFolder sourceFolder, String messageId) {
return sourceFolder.move(messageId, trashFolder);
public boolean deleteEmail(EmailFolder folder, String messageId) {
if (folder instanceof TrashFolder)
return folder.delete(messageId);
else
return folder.move(messageId, trashFolder);
}
/**
* Calls {@link #changePassword(byte[], byte[], byte[])} in a new thread and
* returns a {@link Future} that throws the same exceptions the synchronous
* variant would.
* @param oldPassword
* @param newPassword
* @param confirmNewPassword
*/
public void changePasswordAsync(final byte[] oldPassword, final byte[] newPassword, final byte[] confirmNewPassword) {
passwordChangeResult = Executors.newSingleThreadExecutor().submit(new Callable<Void>() {
@Override
public Void call() throws IOException, GeneralSecurityException, PasswordException {
changePassword(oldPassword, newPassword, confirmNewPassword);
return null;
}
});
}
public void waitForPasswordChange() throws Throwable {
if (passwordChangeResult == null)
return;
try {
passwordChangeResult.get();
} catch (ExecutionException e) {
throw e.getCause();
} finally {
passwordChangeResult = null;
}
}
/**
@ -565,36 +694,55 @@ public class I2PBote implements NetworkStatusSource {
* @param oldPassword
* @param newPassword
* @param confirmNewPassword
* @return An error message if the two new passwords don't match, <code>null</code> otherwise
* @throws IOException
* @throws GeneralSecurityException
* @throws PasswordException
* @throws PasswordException if the old password is incorrect or two new passwords don't match
*/
public String changePassword(byte[] oldPassword, byte[] newPassword, byte[] confirmNewPassword) throws IOException, GeneralSecurityException, PasswordException {
public void changePassword(byte[] oldPassword, byte[] newPassword, byte[] confirmNewPassword) throws IOException, GeneralSecurityException, PasswordException {
changePassword(oldPassword, newPassword, confirmNewPassword, new StatusListener() {
public void updateStatus(String status) {} // Do nothing
});
}
/**
* Reencrypts all encrypted files with a new password
* @param oldPassword
* @param newPassword
* @param confirmNewPassword
* @param lsnr A StatusListener to report progress to
* @throws IOException
* @throws GeneralSecurityException
* @throws PasswordException if the old password is incorrect or two new passwords don't match
*/
public void changePassword(byte[] oldPassword, byte[] newPassword, byte[] confirmNewPassword,
StatusListener lsnr) throws IOException, GeneralSecurityException, PasswordException {
File passwordFile = configuration.getPasswordFile();
lsnr.updateStatus(_("Checking password"));
if (!FileEncryptionUtil.isPasswordCorrect(oldPassword, passwordFile))
return _("The old password is not correct.");
throw new PasswordException(_("The old password is not correct."));
if (!Arrays.equals(newPassword, confirmNewPassword))
return _("The new password and the confirmation password do not match.");
throw new PasswordException(_("The new password and the confirmation password do not match."));
// lock so no files are encrypted with the old password while the password is being changed
passwordCache.lockPassword();
try {
synchronized(passwordCache) {
passwordCache.setPassword(newPassword);
DerivedKey newKey = passwordCache.getKey();
lsnr.updateStatus(_("Re-encrypting identities"));
identities.changePassword(oldPassword, newKey);
lsnr.updateStatus(_("Re-encrypting addressbook"));
addressBook.changePassword(oldPassword, newKey);
for (EmailFolder folder: getEmailFolders())
for (EmailFolder folder: getEmailFolders()) {
lsnr.updateStatus(_("Re-encrypting folder") + " " + folder.getName());
folder.changePassword(oldPassword, newKey);
}
lsnr.updateStatus(_("Updating password file"));
FileEncryptionUtil.writePasswordFile(passwordFile, passwordCache.getPassword(), newKey);
}
finally {
passwordCache.unlockPassword();
}
return null;
}
/**
@ -605,12 +753,17 @@ public class I2PBote implements NetworkStatusSource {
* @throws GeneralSecurityException
* @throws PasswordException
*/
@Override
public void tryPassword(byte[] password) throws IOException, GeneralSecurityException, PasswordException {
File passwordFile = I2PBote.getInstance().getConfiguration().getPasswordFile();
File passwordFile = configuration.getPasswordFile();
boolean correct = FileEncryptionUtil.isPasswordCorrect(password, passwordFile);
if (correct)
passwordCache.setPassword(password);
else
if (correct) {
// Don't cache tried password if none is set. This check is needed
// because IMAP doesn't support a blank password, so the user
// inputs a random string.
if (passwordFile.exists())
passwordCache.setPassword(password);
} else
throw new PasswordException();
}
@ -620,8 +773,8 @@ public class I2PBote implements NetworkStatusSource {
}
/**
* Returns <code>false</code> if a password is set but is not currently cached;
* <code>true</code> otherwise.
* Returns <code>true</code> if a password is set but is not currently cached;
* <code>false</code> otherwise.
*/
public boolean isPasswordRequired() {
return passwordCache.getPassword() == null;
@ -631,11 +784,23 @@ public class I2PBote implements NetworkStatusSource {
public void clearPassword() {
passwordCache.clear();
}
public void addPasswordCacheListener(PasswordCacheListener passwordCacheListener) {
passwordCache.addPasswordCacheListener(passwordCacheListener);
}
public void removePasswordCacheListener(PasswordCacheListener passwordCacheListener) {
passwordCache.removePasswordCacheListener(passwordCacheListener);
}
private Collection<EmailFolder> getEmailFolders() {
public List<File> getUndecryptableFiles() throws PasswordException, IOException, GeneralSecurityException {
return debugSupport.getUndecryptableFiles();
}
public List<EmailFolder> getEmailFolders() {
ArrayList<EmailFolder> folders = new ArrayList<EmailFolder>();
folders.add(outbox);
folders.add(inbox);
folders.add(outbox);
folders.add(sentFolder);
folders.add(trashFolder);
return folders;
@ -649,6 +814,8 @@ public class I2PBote implements NetworkStatusSource {
}
public Set<RelayPeer> getRelayPeers() {
if (peerManager == null)
return new HashSet<RelayPeer>();
return peerManager.getAllPeers();
}
@ -663,12 +830,18 @@ public class I2PBote implements NetworkStatusSource {
}
private void stopAllServices() {
// interrupt all threads
for (I2PAppThread thread: backgroundThreads)
if (thread!=null && thread.isAlive())
thread.interrupt();
awaitShutdown(backgroundThreads, 5 * 1000);
printRunningThreads();
if (backgroundThreads != null) {
// interrupt all threads
for (I2PAppThread thread: backgroundThreads)
if (thread!=null && thread.isAlive())
thread.interrupt();
}
stopImap();
stopSmtp();
if (backgroundThreads != null) {
awaitShutdown(5 * 1000);
printRunningThreads();
}
}
private void printRunningThreads() {
@ -679,14 +852,17 @@ public class I2PBote implements NetworkStatusSource {
log.debug(runningThreads.size() + " threads still running 5 seconds after interrupt()" + (runningThreads.isEmpty()?'.':':'));
for (Thread thread: runningThreads)
log.debug(" " + thread.getName());
if (imapService!=null && imapService.isStarted())
log.debug("IMAP service still running");
if (smtpService!=null && smtpService.isRunning())
log.debug("SMTP service still running");
}
/**
* Waits up to <code>timeout</code> milliseconds for a <code>Collection</code> of threads to end.
* @param threads
* Waits up to <code>timeout</code> milliseconds for the background threads to end.
* @param timeout In milliseconds
*/
private void awaitShutdown(Collection<I2PAppThread> threads, long timeout) {
private void awaitShutdown(long timeout) {
long deadline = System.currentTimeMillis() + timeout; // the time at which any background threads that are still running are interrupted
for (I2PAppThread thread: backgroundThreads)
@ -710,8 +886,31 @@ public class I2PBote implements NetworkStatusSource {
connectTask.startSignal.countDown();
}
public void networkStatusChanged() {
synchronized (networkStatusListeners) {
for (NetworkStatusListener nsl : networkStatusListeners)
nsl.networkStatusChanged();
}
}
@Override
public void addNetworkStatusListener(NetworkStatusListener networkStatusListener) {
synchronized (networkStatusListeners) {
networkStatusListeners.add(networkStatusListener);
}
}
@Override
public void removeNetworkStatusListener(NetworkStatusListener networkStatusListener) {
synchronized (networkStatusListeners) {
networkStatusListeners.remove(networkStatusListener);
}
}
@Override
public NetworkStatus getNetworkStatus() {
if (connectTask == null)
return NetworkStatus.NOT_STARTED;
if (!connectTask.isDone())
return connectTask.getNetworkStatus();
else if (dht != null)
@ -766,20 +965,24 @@ public class I2PBote implements NetworkStatusSource {
@Override
public void run() {
status = NetworkStatus.DELAY;
networkStatusChanged();
try {
startSignal.await(STARTUP_DELAY, TimeUnit.MINUTES);
status = NetworkStatus.CONNECTING;
networkStatusChanged();
initializeSession();
initializeServices();
startAllServices();
doneSignal.countDown();
networkStatusChanged();
} catch (InterruptedException e) {
log.debug("ConnectTask interrupted, exiting");
} catch (Exception e) {
status = NetworkStatus.ERROR;
networkStatusChanged();
error = e;
log.error("Can't initialize the application.", e);
}
}
}
}
}

View File

@ -0,0 +1,37 @@
/**
* Copyright (C) 2009 HungryHobo@mail.i2p
*
* The GPG fingerprint for HungryHobo@mail.i2p is:
* 6DD3 EAA2 9990 29BC 4AD2 7486 1E2C 7B61 76DC DC12
*
* This file is part of I2P-Bote.
* I2P-Bote is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* I2P-Bote is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with I2P-Bote. If not, see <http://www.gnu.org/licenses/>.
*/
package i2p.bote;
import i2p.bote.email.Email;
import i2p.bote.fileencryption.PasswordException;
import java.io.IOException;
import java.security.GeneralSecurityException;
import javax.mail.MessagingException;
import net.i2p.data.DataFormatException;
public interface MailSender {
void sendEmail(Email email) throws MessagingException, PasswordException, IOException, GeneralSecurityException, DataFormatException;
}

View File

@ -0,0 +1,9 @@
package i2p.bote;
/**
* Listens to general status updates from methods.
*/
public interface StatusListener {
void updateStatus(String status);
}

View File

@ -43,6 +43,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Properties;
import java.util.concurrent.ThreadFactory;
import javax.mail.MessagingException;
@ -50,6 +51,7 @@ import javax.mail.Part;
import net.i2p.I2PAppContext;
import net.i2p.crypto.SHA256Generator;
import net.i2p.crypto.SessionKeyManager;
import net.i2p.data.Base32;
import net.i2p.data.DataFormatException;
import net.i2p.data.Destination;
@ -87,19 +89,32 @@ public class Util {
* @throws MessagingException
* @throws IOException */
public static String getHumanReadableSize(Part part) throws IOException, MessagingException {
return getHumanReadableSize(getPartSize(part));
}
public static long getPartSize(Part part) throws IOException, MessagingException {
// find size in bytes
InputStream inputStream = part.getInputStream();
byte[] buffer = new byte[32*1024];
long totalBytes = 0;
int bytesRead;
do {
bytesRead = inputStream.read(buffer, 0, buffer.length);
if (bytesRead > 0)
totalBytes += bytesRead;
} while (bytesRead > 0);
// format to a string
return getHumanReadableSize(totalBytes);
InputStream inputStream = null;
try {
inputStream = part.getInputStream();
byte[] buffer = new byte[32 * 1024];
int bytesRead;
do {
bytesRead = inputStream.read(buffer, 0, buffer.length);
if (bytesRead > 0)
totalBytes += bytesRead;
} while (bytesRead > 0);
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
}
}
}
return totalBytes;
}
private static String getHumanReadableSize(long numBytes) {
@ -263,6 +278,7 @@ public class Util {
public static Destination createDestination(ByteBuffer buffer) throws DataFormatException {
byte[] bytes = new byte[388];
// read 384 bytes, leave the last 3 bytes zero
// TODO This is NOT compatible with newer key types!
buffer.get(bytes, 0, 384);
Destination peer = new Destination();
peer.readBytes(bytes, 0);
@ -366,22 +382,11 @@ public class Util {
return valid;
}
/**
* Makes a file readable and writable only by the current OS user,
* if the operating system supports it. Errors are ignored.
* @param file
*/
public static void makePrivate(File file) {
file.setReadable(false, false);
file.setReadable(true, true);
file.setWritable(false, false);
file.setWritable(true, true);
}
/** Encrypts data with an I2P public key */
public static byte[] encrypt(byte data[], PublicKey key) {
I2PAppContext appContext = I2PAppContext.getGlobalContext();
SessionKey sessionKey = appContext.sessionKeyManager().createSession(key);
SessionKeyManager sessionKeyMgr = new net.i2p.crypto.SessionKeyManager(appContext) { };
SessionKey sessionKey = sessionKeyMgr.createSession(key);
return appContext.elGamalAESEngine().encrypt(data, key, sessionKey, null, null, null, 0);
}
@ -391,7 +396,9 @@ public class Util {
*/
public static byte[] decrypt(byte data[], PrivateKey key) throws DataFormatException {
I2PAppContext appContext = I2PAppContext.getGlobalContext();
return appContext.elGamalAESEngine().decrypt(data, key, appContext.sessionKeyManager());
SessionKeyManager sessionKeyMgr = new net.i2p.crypto.SessionKeyManager(appContext) {
};
return appContext.elGamalAESEngine().decrypt(data, key, sessionKeyMgr);
}
/** Overwrites a <code>byte</code> array with zeros */
@ -422,4 +429,28 @@ public class Util {
return null;
}
}
public static boolean getBooleanParameter(Properties properties, String parameterName, boolean defaultValue) {
String stringValue = properties.getProperty(parameterName);
if ("true".equalsIgnoreCase(stringValue) || "yes".equalsIgnoreCase(stringValue) || "on".equalsIgnoreCase(stringValue) || "1".equals(stringValue))
return true;
else if ("false".equalsIgnoreCase(stringValue) || "no".equalsIgnoreCase(stringValue) || "off".equalsIgnoreCase(stringValue) || "0".equals(stringValue))
return false;
else if (stringValue == null)
return defaultValue;
else
throw new IllegalArgumentException("<" + stringValue + "> is not a legal value for the boolean parameter <" + parameterName + ">");
}
public static int getIntParameter(Properties properties, String parameterName, int defaultValue) {
String stringValue = properties.getProperty(parameterName);
if (stringValue == null)
return defaultValue;
else
try {
return new Integer(stringValue);
} catch (NumberFormatException e) {
throw new NumberFormatException("Can't convert value <" + stringValue + "> for parameter <" + parameterName + "> to int.");
}
}
}

View File

@ -21,7 +21,6 @@
package i2p.bote.addressbook;
import i2p.bote.Util;
import i2p.bote.email.EmailDestination;
import i2p.bote.fileencryption.DerivedKey;
import i2p.bote.fileencryption.EncryptedInputStream;
@ -36,7 +35,6 @@ import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@ -49,6 +47,7 @@ import java.util.SortedSet;
import java.util.TreeSet;
import net.i2p.util.Log;
import net.i2p.util.SecureFileOutputStream;
/**
* Implements the private address book. Holds a set of {@link Contact}s
@ -142,7 +141,7 @@ public class AddressBook {
public void save() throws IOException, PasswordException, GeneralSecurityException {
initializeIfNeeded();
OutputStream encryptedStream = new EncryptedOutputStream(new FileOutputStream(addressFile), passwordHolder);
OutputStream encryptedStream = new EncryptedOutputStream(new SecureFileOutputStream(addressFile), passwordHolder);
SortedProperties properties = new SortedProperties();
try {
int index = 0;
@ -158,7 +157,6 @@ public class AddressBook {
index++;
}
properties.store(new OutputStreamWriter(encryptedStream, "UTF-8"), null);
Util.makePrivate(addressFile);
} catch (IOException e) {
log.error("Can't save email identities to file <" + addressFile.getAbsolutePath() + ">.", e);
throw e;

View File

@ -21,27 +21,37 @@
package i2p.bote.crypto;
import java.util.Arrays;
import java.security.GeneralSecurityException;
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import net.i2p.I2PAppContext;
import net.i2p.data.SessionKey;
import net.i2p.util.Log;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.paddings.PKCS7Padding;
/**
* Implements {@link #toByteArray(PublicKeyPair)} and {@link #toByteArray(PrivateKeyPair)},
* and provides methods for AES encryption and decryption.
*/
public abstract class AbstractCryptoImplementation implements CryptoImplementation {
private static final int BLOCK_SIZE = 16; // the AES block size for padding. Not to be confused with the AES key size.
protected I2PAppContext appContext;
private Log log = new Log(AbstractCryptoImplementation.class);
protected AbstractCryptoImplementation() {
private Cipher aesCipher;
protected AbstractCryptoImplementation() throws GeneralSecurityException {
appContext = I2PAppContext.getGlobalContext();
try {
aesCipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
} catch (NoSuchPaddingException e) {
// SUN provider incorrectly calls it PKCS5Padding
aesCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
}
}
/** This implementation returns the whole set of Base64 characters. */
@Override
public String getBase64InitialCharacters() {
return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
}
@Override
@ -66,34 +76,27 @@ public abstract class AbstractCryptoImplementation implements CryptoImplementati
return encodedKeys;
}
protected byte[] encryptAes(byte[] data, byte[] key, byte[] iv) {
// pad the data
int unpaddedLength = data.length;
data = Arrays.copyOf(data, unpaddedLength + BLOCK_SIZE - unpaddedLength%BLOCK_SIZE); // make data.length a multiple of BLOCK_SIZE; if the length is a multiple of BLOCK_LENGTH, add a block of zeros
PKCS7Padding padding = new PKCS7Padding();
int numAdded = padding.addPadding(data, unpaddedLength);
if (log.shouldLog(Log.DEBUG) && numAdded != BLOCK_SIZE-unpaddedLength%BLOCK_SIZE)
log.error("Error: " + numAdded + " pad bytes added, expected: " + (BLOCK_SIZE-unpaddedLength%BLOCK_SIZE));
protected byte[] encryptAes(byte[] data, byte[] key, byte[] iv) throws GeneralSecurityException {
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
IvParameterSpec ivps = new IvParameterSpec(iv, 0, 16);
aesCipher.init(Cipher.ENCRYPT_MODE, keySpec, ivps, appContext.random());
byte[] encryptedData = new byte[data.length];
SessionKey sessionKey = new SessionKey(key);
appContext.aes().encrypt(data, 0, encryptedData, 0, sessionKey, iv, data.length); // this method also checks that data.length is divisible by 16
return encryptedData;
byte[] encryptedData = new byte[aesCipher.getOutputSize(data.length)];
int encLen = aesCipher.doFinal(data, 0, data.length, encryptedData, 0);
byte[] ret = new byte[encLen];
System.arraycopy(encryptedData, 0, ret, 0, encLen);
return ret;
}
protected byte[] decryptAes(byte[] data, byte[] key, byte[] iv) throws InvalidCipherTextException {
SessionKey sessionKey = new SessionKey(key);
byte[] decryptedData = new byte[data.length];
if (data.length%BLOCK_SIZE != 0)
log.error("Length of encrypted data is not divisible by " + BLOCK_SIZE + ". Length=" + decryptedData.length);
appContext.aes().decrypt(data, 0, decryptedData, 0, sessionKey, iv, data.length);
// unpad the decrypted data
byte[] lastBlock = Arrays.copyOfRange(decryptedData, decryptedData.length-iv.length, decryptedData.length);
PKCS7Padding padding = new PKCS7Padding();
int padCount = padding.padCount(lastBlock);
decryptedData = Arrays.copyOf(decryptedData, decryptedData.length-padCount);
return decryptedData;
protected byte[] decryptAes(byte[] data, byte[] key, byte[] iv) throws GeneralSecurityException {
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
IvParameterSpec ivps = new IvParameterSpec(iv, 0, 16);
aesCipher.init(Cipher.DECRYPT_MODE, keySpec, ivps, appContext.random());
byte[] decryptedData = new byte[aesCipher.getOutputSize(data.length)];
int decLen = aesCipher.doFinal(data, 0, data.length, decryptedData, 0);
byte[] ret = new byte[decLen];
System.arraycopy(decryptedData, 0, ret, 0, decLen);
return ret;
}
}

View File

@ -21,7 +21,10 @@
package i2p.bote.crypto;
import java.lang.reflect.Constructor;
import java.security.GeneralSecurityException;
import java.security.Provider;
import java.security.Security;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@ -29,6 +32,18 @@ import java.util.List;
import net.i2p.util.Log;
public class CryptoFactory {
static {
if (Security.getProvider("BC") == null) {
try {
Class<?> cls = Class.forName("org.bouncycastle.jce.provider.BouncyCastleProvider");
Constructor<?> con = cls.getConstructor(new Class[0]);
Provider bc = (Provider)con.newInstance(new Object[0]);
Security.addProvider(bc);
} catch (Exception e) {
}
}
}
private static List<CryptoImplementation> instances;
public synchronized static CryptoImplementation getInstance(int id) {
@ -50,15 +65,23 @@ public class CryptoFactory {
private static void init() {
instances = Collections.synchronizedList(new ArrayList<CryptoImplementation>());
instances.add(new ElGamal2048_DSA1024());
Log log = new Log(CryptoFactory.class);
try {
instances.add(new ElGamal2048_DSA1024());
} catch (GeneralSecurityException e) {
log.error("Error creating ElGamal2048_DSA1024.", e);
}
try {
instances.add(new ECDH256_ECDSA256());
instances.add(new ECDH521_ECDSA521());
}
catch (GeneralSecurityException e) {
Log log = new Log(CryptoFactory.class);
log.error("Error creating ECDH256_ECDSA256 or ECDH521_ECDSA521.", e);
}
instances.add(new NTRUEncrypt1087_GMSS512());
try {
instances.add(new NTRUEncrypt1087_GMSS512());
} catch (GeneralSecurityException e) {
log.error("Error creating NTRUEncrypt1087_GMSS512.", e);
}
}
}

View File

@ -28,8 +28,6 @@ import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;
import org.bouncycastle.crypto.InvalidCipherTextException;
/**
* Interface for all encryption/signature algorithm combinations supported by
* I2P-Bote. Also contains methods for converting between Base64 keys and
@ -68,6 +66,9 @@ public interface CryptoImplementation {
KeyPair generateSigningKeyPair() throws GeneralSecurityException;
/** Returns all possible characters that a Base64-encoded Email Destination can start with. */
String getBase64InitialCharacters();
//
// Key conversion
//
@ -100,6 +101,11 @@ public interface CryptoImplementation {
*/
String toBase64(PublicKeyPair keyPair) throws GeneralSecurityException;
/**
* Converts a public encryption key to Base64.
*/
String encryptionKeyToBase64(PublicKey key) throws GeneralSecurityException;
/**
* The toBase64 methods are incompatible with the toByteArray methods.
* Using this method may result in shorter strings than calling toByteArray and Base64-encoding the byte array
@ -127,7 +133,7 @@ public interface CryptoImplementation {
byte[] encrypt(byte[] data, PublicKey key) throws GeneralSecurityException;
/** This method takes a public key in addition to the private key because some algorithms need the public key for decryption. */
byte[] decrypt(byte[] data, PublicKey publicKey, PrivateKey privateKey) throws GeneralSecurityException, InvalidCipherTextException;
byte[] decrypt(byte[] data, PublicKey publicKey, PrivateKey privateKey) throws GeneralSecurityException;
/**
* @param data

View File

@ -24,7 +24,6 @@ package i2p.bote.crypto;
import i2p.bote.Util;
import java.security.GeneralSecurityException;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.interfaces.ECPublicKey;
@ -35,13 +34,10 @@ import java.util.Arrays;
import net.i2p.data.Base64;
import org.bouncycastle.jce.ECPointUtil;
import org.bouncycastle.jce.provider.asymmetric.ec.EC5Util;
public class ECDH256_ECDSA256 extends ECDH_ECDSA {
public ECDH256_ECDSA256() throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
super("P-256", 33); // Use the NIST P-256 curve, also known as secp256r1
public ECDH256_ECDSA256() throws GeneralSecurityException {
super("P-256", "SHA256withECDSA", 33); // Use the NIST P-256 curve, also known as secp256r1
}
@Override
@ -64,16 +60,21 @@ public class ECDH256_ECDSA256 extends ECDH_ECDSA {
return 172;
}
@Override
public String getBase64InitialCharacters() {
return "ghijklmnopqrstuvwxyz0123456789";
}
@Override
protected byte[] toByteArray(PublicKey key) {
ECPublicKey ecKey = castToEcKey(key);
return EC5Util.convertPoint(ecKey.getParams(), ecKey.getW(), true).getEncoded();
return ECUtils.encodePoint(ecKey.getParams(), ecKey.getW(), true);
}
@Override
protected ECPublicKeySpec createPublicKeySpec(byte[] encodedKey) throws InvalidKeySpecException, NoSuchAlgorithmException {
// decompress into an EC point
ECPoint w = ECPointUtil.decodePoint(ecParameterSpec.getCurve(), encodedKey);
ECPoint w = ECUtils.decodePoint(ecParameterSpec.getCurve(), encodedKey);
// make a public key from the public point w
ECPublicKeySpec publicKeySpec = new ECPublicKeySpec(w, ecParameterSpec);
@ -93,9 +94,4 @@ public class ECDH256_ECDSA256 extends ECDH_ECDSA {
System.arraycopy(sigKeyBytes, 0, bytes, encrKeyBytes.length, sigKeyBytes.length);
return createPrivateKeyPair(bytes);
}
@Override
protected BouncyECDSASigner getSigner() {
return new BouncyECDSASignerSHA256();
}
}

View File

@ -24,7 +24,6 @@ package i2p.bote.crypto;
import i2p.bote.Util;
import java.security.GeneralSecurityException;
import java.security.InvalidAlgorithmParameterException;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.interfaces.ECPublicKey;
@ -36,17 +35,14 @@ import java.util.Arrays;
import net.i2p.data.Base64;
import net.i2p.util.Log;
import org.bouncycastle.jce.ECPointUtil;
import org.bouncycastle.jce.provider.asymmetric.ec.EC5Util;
/**
* TODO document the 66-byte format
*/
public class ECDH521_ECDSA521 extends ECDH_ECDSA {
private Log log = new Log(ECDH521_ECDSA521.class);
public ECDH521_ECDSA521() throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
super("P-521", 66); // Use the NIST P-521 curve, also known as secp521r1
public ECDH521_ECDSA521() throws GeneralSecurityException {
super("P-521", "SHA512withECDSA", 66); // Use the NIST P-521 curve, also known as secp521r1
}
@Override
@ -72,7 +68,7 @@ public class ECDH521_ECDSA521 extends ECDH_ECDSA {
@Override
protected byte[] toByteArray(PublicKey key) {
ECPublicKey ecKey = castToEcKey(key);
byte[] bouncyCompressedKey = EC5Util.convertPoint(ecKey.getParams(), ecKey.getW(), true).getEncoded();
byte[] bouncyCompressedKey = ECUtils.encodePoint(ecKey.getParams(), ecKey.getW(), true);
// shorten by one byte (bouncyCompressedKey[0] is either 2 or 3, bouncyCompressedKey[1] is either 0 or 1, so they can fit in two bits)
if (bouncyCompressedKey[0]!=2 && bouncyCompressedKey[0]!=3)
@ -93,7 +89,7 @@ public class ECDH521_ECDSA521 extends ECDH_ECDSA {
bouncyCompressedKey[0] = (byte)((bouncyCompressedKey[1] >> 1) + 2);
bouncyCompressedKey[1] &= 1;
// decompress into an EC point
ECPoint w = ECPointUtil.decodePoint(ecParameterSpec.getCurve(), bouncyCompressedKey);
ECPoint w = ECUtils.decodePoint(ecParameterSpec.getCurve(), bouncyCompressedKey);
// make a public key from the public point w
ECPublicKeySpec publicKeySpec = new ECPublicKeySpec(w, ecParameterSpec);
@ -108,9 +104,4 @@ public class ECDH521_ECDSA521 extends ECDH_ECDSA {
byte[] bytes = Base64.decode(base64);
return createPrivateKeyPair(bytes);
}
@Override
protected BouncyECDSASigner getSigner() {
return new BouncyECDSASignerSHA512();
}
}

View File

@ -28,38 +28,26 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.GeneralSecurityException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SignatureException;
import java.security.Signature;
import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;
import java.security.spec.ECParameterSpec;
import java.security.spec.ECPrivateKeySpec;
import java.security.spec.ECPublicKeySpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.util.Arrays;
import javax.crypto.KeyAgreement;
import net.i2p.data.Base64;
import net.i2p.util.Log;
import org.bouncycastle.asn1.nist.NISTNamedCurves;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.jce.provider.asymmetric.ec.KeyAgreement;
import org.bouncycastle.jce.provider.asymmetric.ec.KeyFactory;
import org.bouncycastle.jce.provider.asymmetric.ec.KeyPairGenerator;
import org.bouncycastle.jce.provider.asymmetric.ec.Signature;
import org.bouncycastle.jce.provider.asymmetric.ec.Signature.ecDSA256;
import org.bouncycastle.jce.provider.asymmetric.ec.Signature.ecDSA512;
import org.bouncycastle.jce.spec.ECNamedCurveSpec;
/**
* Abstract base class for ECC (ECDH and ECDSA).
* <p/>
@ -79,35 +67,45 @@ import org.bouncycastle.jce.spec.ECNamedCurveSpec;
*/
public abstract class ECDH_ECDSA extends AbstractCryptoImplementation {
private static final int IV_SIZE = 16; // length of the AES initialization vector
protected int keyLengthBytes;
protected ECNamedCurveSpec ecParameterSpec;
private KeyPairGenerator.ECDH encryptionKeyPairGenerator;
private KeyPairGenerator.ECDSA signingKeyPairGenerator;
private BouncyECDHKeyFactory ecdhKeyFactory;
private BouncyECDSAKeyFactory ecdsaKeyFactory;
protected ECParameterSpec ecParameterSpec;
private KeyPairGenerator encryptionKeyPairGenerator;
private KeyPairGenerator signingKeyPairGenerator;
private KeyFactory ecdhKeyFactory;
private KeyFactory ecdsaKeyFactory;
private Signature signatureAlg;
private Signature altSignatureAlg;
private Log log = new Log(ECDH_ECDSA.class);
/**
*
* @param curveName
* @param bcCurveName
* @param sigName
* @param keyLengthBytes Length of a byte array encoding of one (public or private) key
* @throws NoSuchAlgorithmException
* @throws InvalidAlgorithmParameterException
* @throws GeneralSecurityException
*/
ECDH_ECDSA(String curveName, int keyLengthBytes) throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
X9ECParameters params = NISTNamedCurves.getByName(curveName);
ecParameterSpec = new ECNamedCurveSpec(curveName, params.getCurve(), params.getG(), params.getN(), params.getH(), null);
ECDH_ECDSA(String curveName, String sigName, int keyLengthBytes) throws GeneralSecurityException {
super();
ecParameterSpec = ECUtils.getParameters(curveName);
signatureAlg = Signature.getInstance(sigName);
// Backwards-compatibility with old ECDSA-521 signatures that used SHA-256
if ("P-521".equals(curveName))
altSignatureAlg = Signature.getInstance("SHA256withECDSA");
this.keyLengthBytes = keyLengthBytes;
encryptionKeyPairGenerator = new KeyPairGenerator.ECDH();
encryptionKeyPairGenerator.initialize(ecParameterSpec);
signingKeyPairGenerator = new KeyPairGenerator.ECDSA();
signingKeyPairGenerator.initialize(ecParameterSpec);
ecdhKeyFactory = new BouncyECDHKeyFactory();
ecdsaKeyFactory = new BouncyECDSAKeyFactory();
encryptionKeyPairGenerator = KeyPairGenerator.getInstance("ECDH");
encryptionKeyPairGenerator.initialize(ecParameterSpec, appContext.random());
signingKeyPairGenerator = KeyPairGenerator.getInstance("ECDSA");
signingKeyPairGenerator.initialize(ecParameterSpec, appContext.random());
ecdhKeyFactory = KeyFactory.getInstance("ECDH");
ecdsaKeyFactory = KeyFactory.getInstance("ECDSA");
}
@Override
@ -224,6 +222,11 @@ public abstract class ECDH_ECDSA extends AbstractCryptoImplementation {
return toBase64(keyPair.encryptionKey) + toBase64(keyPair.signingKey);
}
@Override
public String encryptionKeyToBase64(PublicKey key) throws GeneralSecurityException {
return toBase64(key);
}
/**
* This method assumes a base64 encoding of a byte array encoded key always starts
* with an 'A', which is currently the case for all subclasses.
@ -284,14 +287,13 @@ public abstract class ECDH_ECDSA extends AbstractCryptoImplementation {
* <li/>Use that secret as a key to encrypt the message with AES.<br/>
* <li/>Return the encrypted message and the ephemeral public key generated in step 1.<br/>
* </ol>
* @throws InvalidKeyException
* @throws NoSuchAlgorithmException
* @throws GeneralSecurityException
*/
@Override
public byte[] encrypt(byte[] data, PublicKey encryptionKey) throws InvalidKeyException, NoSuchAlgorithmException {
public byte[] encrypt(byte[] data, PublicKey encryptionKey) throws GeneralSecurityException {
// generate an ephemeral EC key and a shared secret
KeyPair ephKeyPair = encryptionKeyPairGenerator.generateKeyPair();
ECDHKeyAgreement keyAgreement = new ECDHKeyAgreement();
KeyAgreement keyAgreement = KeyAgreement.getInstance("ECDH");
keyAgreement.init(ephKeyPair.getPrivate());
keyAgreement.doPhase(encryptionKey, true);
byte[] sharedSecret = keyAgreement.generateSecret();
@ -324,13 +326,10 @@ public abstract class ECDH_ECDSA extends AbstractCryptoImplementation {
* <li/>Use that secret as a key to decrypt the message with AES.<br/>
* </ol>
* The public key is not used.
* @throws NoSuchAlgorithmException
* @throws InvalidKeyException
* @throws InvalidKeySpecException
* @throws InvalidCipherTextException
* @throws GeneralSecurityException
*/
@Override
public byte[] decrypt(byte[] data, PublicKey publicKey, PrivateKey privateKey) throws NoSuchAlgorithmException, InvalidKeyException, InvalidKeySpecException, InvalidCipherTextException {
public byte[] decrypt(byte[] data, PublicKey publicKey, PrivateKey privateKey) throws GeneralSecurityException {
ByteArrayInputStream byteStream = new ByteArrayInputStream(data);
try {
// read the ephemeral public key
@ -340,7 +339,7 @@ public abstract class ECDH_ECDSA extends AbstractCryptoImplementation {
PublicKey ephPublicKey = ecdhKeyFactory.generatePublic(ephPublicKeySpec);
// reconstruct the shared secret
ECDHKeyAgreement keyAgreement = new ECDHKeyAgreement();
KeyAgreement keyAgreement = KeyAgreement.getInstance("ECDH");
keyAgreement.init(privateKey);
keyAgreement.doPhase(ephPublicKey, true);
byte[] sharedSecret = keyAgreement.generateSecret();
@ -362,144 +361,32 @@ public abstract class ECDH_ECDSA extends AbstractCryptoImplementation {
}
protected abstract ECPublicKeySpec createPublicKeySpec(byte[] encodedKey) throws InvalidKeySpecException, NoSuchAlgorithmException;
@Override
public byte[] sign(byte[] data, PrivateKey privateKey, KeyUpdateHandler keyupdateHandler) throws NoSuchAlgorithmException, InvalidKeyException, SignatureException {
// BouncyECDSASignerSHA512 signatureAlg = new BouncyECDSASignerSHA512();
BouncyECDSASigner signatureAlg = getSigner();
public byte[] sign(byte[] data, PrivateKey privateKey, KeyUpdateHandler keyupdateHandler) throws GeneralSecurityException {
signatureAlg.initSign(privateKey);
signatureAlg.update(data);
byte[] signature = signatureAlg.sign();
return signature;
}
/** Returns the signature algorithm to use for signing (not verifying!). */
protected abstract BouncyECDSASigner getSigner();
/**
* Returns <code>true</code> if the signature is valid either for ECDSA with SHA-256 or
* ECDSA with SHA-512. This will change in a future version; ECDSA-521 will be SHA-512 only.
* @return <code>true</code> if the signature is valid.
*/
@Override
public boolean verify(byte[] data, byte[] signature, PublicKey key) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeyException, SignatureException {
BouncyECDSASigner[] signatureAlgs = new BouncyECDSASigner[] {new BouncyECDSASignerSHA512(), new BouncyECDSASignerSHA256()};
for (BouncyECDSASigner signatureAlg: signatureAlgs) {
signatureAlg.initVerify(key);
signatureAlg.update(data);
boolean valid = signatureAlg.verify(signature);
if (valid)
return true;
}
return false;
}
/** This class exposes the protected <code>engine*</code> methods in {@link KeyAgreement.DH} */
private class ECDHKeyAgreement extends KeyAgreement.DH {
public void init(Key key) throws InvalidKeyException {
engineInit(key, appContext.random());
}
public void doPhase(Key key, boolean lastPhase) throws InvalidKeyException, IllegalStateException {
engineDoPhase(key, lastPhase);
}
public byte[] generateSecret() {
return engineGenerateSecret();
}
}
/** This class exposes the protected <code>engine*</code> methods in {@link KeyFactory.ECDH} */
@SuppressWarnings("unchecked") // this eliminates a warning in the ant build caused by org.bouncycastle.jce.provider.asymmetric.ec.KeyFactory.engineGetKeySpec(java.security.Key,java.lang.Class)
private class BouncyECDHKeyFactory extends KeyFactory.ECDH {
public PublicKey generatePublic(KeySpec keySpec) throws InvalidKeySpecException {
return engineGeneratePublic(keySpec);
}
public PrivateKey generatePrivate(KeySpec keySpec) throws InvalidKeySpecException {
return engineGeneratePrivate(keySpec);
}
}
/** This class exposes the protected <code>engine*</code> methods in {@link KeyFactory.ECDSA} */
@SuppressWarnings("unchecked") // this eliminates a warning in the ant build caused by org.bouncycastle.jce.provider.asymmetric.ec.KeyFactory.engineGetKeySpec(java.security.Key,java.lang.Class)
private class BouncyECDSAKeyFactory extends KeyFactory.ECDSA {
public PublicKey generatePublic(KeySpec keySpec) throws InvalidKeySpecException {
return engineGeneratePublic(keySpec);
}
public PrivateKey generatePrivate(KeySpec keySpec) throws InvalidKeySpecException {
return engineGeneratePrivate(keySpec);
}
}
protected interface BouncyECDSASigner {
void initSign(PrivateKey privateKey) throws InvalidKeyException;
void initVerify(PublicKey publicKey) throws InvalidKeyException;
void update(byte[] data) throws SignatureException;
byte[] sign() throws SignatureException;
boolean verify(byte[] signature) throws SignatureException;
}
/**
* This class exposes the protected <code>engine*</code> methods in {@link ecDSA256}
* which implements ECDSA with SHA-256.
*/
protected class BouncyECDSASignerSHA256 extends ecDSA256 implements BouncyECDSASigner {
public final void initSign(PrivateKey privateKey) throws InvalidKeyException {
engineInitSign(privateKey);
}
public final void initVerify(PublicKey publicKey) throws InvalidKeyException {
engineInitVerify(publicKey);
}
public final void update(byte[] data) throws SignatureException {
engineUpdate(data, 0, data.length);
}
public final byte[] sign() throws SignatureException {
return engineSign();
}
public final boolean verify(byte[] signature) throws SignatureException {
return engineVerify(signature);
}
}
/**
* This class exposes the protected <code>engine*</code> methods in {@link ecDSA512}
* which implements ECDSA with SHA-512.
*/
protected class BouncyECDSASignerSHA512 extends ecDSA512 implements BouncyECDSASigner {
public final void initSign(PrivateKey privateKey) throws InvalidKeyException {
engineInitSign(privateKey);
}
public final void initVerify(PublicKey publicKey) throws InvalidKeyException {
engineInitVerify(publicKey);
}
public final void update(byte[] data) throws SignatureException {
engineUpdate(data, 0, data.length);
}
public final byte[] sign() throws SignatureException {
return engineSign();
}
public final boolean verify(byte[] signature) throws SignatureException {
return engineVerify(signature);
public boolean verify(byte[] data, byte[] signature, PublicKey key) throws GeneralSecurityException {
signatureAlg.initVerify(key);
signatureAlg.update(data);
boolean valid = signatureAlg.verify(signature);
// Backwards-compatibility with old ECDSA-521 signatures that used SHA-256
if (!valid && altSignatureAlg != null) {
altSignatureAlg.initVerify(key);
altSignatureAlg.update(data);
valid = altSignatureAlg.verify(signature);
}
return valid;
}
}

View File

@ -0,0 +1,38 @@
package i2p.bote.crypto;
import java.security.spec.ECParameterSpec;
import java.security.spec.ECPoint;
import java.security.spec.EllipticCurve;
import org.bouncycastle.asn1.nist.NISTNamedCurves;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util;
import org.bouncycastle.jce.ECPointUtil;
import org.bouncycastle.jce.spec.ECNamedCurveSpec;
/**
* A wrapper around the BouncyCastle EC classes.
* <p/>
* On Android, this is replaced by a wrapper around the SpongyCastle
* EC classes.
*/
public class ECUtils {
public static ECParameterSpec getParameters(String curveName) {
X9ECParameters params = NISTNamedCurves.getByName(curveName);
return new ECNamedCurveSpec(curveName, params.getCurve(), params.getG(), params.getN(), params.getH(), null);
}
public static byte[] encodePoint(
ECParameterSpec ecSpec,
ECPoint point,
boolean withCompression) {
org.bouncycastle.math.ec.ECPoint bcPoint = EC5Util.convertPoint(ecSpec, point, withCompression);
return bcPoint.getEncoded();
}
public static ECPoint decodePoint(
EllipticCurve curve,
byte[] encoded) {
return ECPointUtil.decodePoint(curve, encoded);
}
}

View File

@ -49,7 +49,10 @@ import net.i2p.data.Signature;
* Uses the I2P crypto routines.
*/
public class ElGamal2048_DSA1024 extends AbstractCryptoImplementation {
public ElGamal2048_DSA1024() throws GeneralSecurityException {
super();
}
@Override
public String getName() {
return Util._("2048-bit ElGamal Encryption");
@ -89,6 +92,11 @@ public class ElGamal2048_DSA1024 extends AbstractCryptoImplementation {
public String toBase64(PublicKeyPair keyPair) throws GeneralSecurityException {
return Base64.encode(toByteArray(keyPair));
}
@Override
public String encryptionKeyToBase64(PublicKey key) throws GeneralSecurityException {
return Base64.encode(key.getEncoded());
}
@Override
public String toBase64(PrivateKeyPair keyPair) throws GeneralSecurityException {

View File

@ -31,12 +31,10 @@ import java.security.InvalidAlgorithmParameterException;
import java.security.KeyException;
import java.security.KeyPair;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Arrays;
import net.i2p.I2PAppContext;
import net.i2p.data.Base64;
import net.sf.ntru.encrypt.EncryptionKeyPair;
import net.sf.ntru.encrypt.EncryptionParameters;
@ -44,8 +42,6 @@ import net.sf.ntru.encrypt.EncryptionPrivateKey;
import net.sf.ntru.encrypt.EncryptionPublicKey;
import net.sf.ntru.encrypt.NtruEncrypt;
import org.bouncycastle.crypto.InvalidCipherTextException;
import de.flexiprovider.api.exceptions.InvalidKeySpecException;
import de.flexiprovider.api.keys.KeySpec;
import de.flexiprovider.pki.PKCS8EncodedKeySpec;
@ -103,13 +99,13 @@ public class NTRUEncrypt1087_GMSS512 extends AbstractCryptoImplementation {
private static final int PRIVATE_SIGNING_KEY_BYTES = 57180 + 4 + 14400; // ASN1-encoded private key + 4 length bytes + padding
private static final int ENCRYPTED_LENGTH_BYTES = PUBLIC_ENCRYPTION_KEY_BYTES; // length of an NTRU-encrypted message (no AES)
private static final int BLOCK_SIZE = 16; // length of the AES initialization vector; also the AES block size for padding. Not to be confused with the AES key size.
private I2PAppContext appContext;
private GMSSKeyFactory gmssKeyFactory;
private NtruEncrypt ntruEngine;
public NTRUEncrypt1087_GMSS512() {
appContext = I2PAppContext.getGlobalContext();
public NTRUEncrypt1087_GMSS512() throws GeneralSecurityException {
super();
gmssKeyFactory = new GMSSKeyFactory();
ntruEngine = new NtruEncrypt(NTRUENCRYPT_PARAMETERS);
}
@ -172,6 +168,11 @@ public class NTRUEncrypt1087_GMSS512 extends AbstractCryptoImplementation {
return base64.substring(0, base64.length()-1);
}
@Override
public String encryptionKeyToBase64(PublicKey key) throws GeneralSecurityException {
return Base64.encode(key.getEncoded());
}
@Override
public String toBase64(PrivateKeyPair keyPair) {
String base64 = Base64.encode(toByteArray(keyPair));
@ -217,10 +218,10 @@ public class NTRUEncrypt1087_GMSS512 extends AbstractCryptoImplementation {
/**
* Only accepts <code>NtruEncrypt1087PublicKey</code>s.
* @throws NoSuchAlgorithmException
* @throws GeneralSecurityException
*/
@Override
public byte[] encrypt(byte[] data, PublicKey key) throws NoSuchAlgorithmException {
public byte[] encrypt(byte[] data, PublicKey key) throws GeneralSecurityException {
byte[] symmKey = new byte[32];
appContext.random().nextBytes(symmKey);
@ -247,11 +248,10 @@ public class NTRUEncrypt1087_GMSS512 extends AbstractCryptoImplementation {
/**
* Only accepts <code>NtruEncrypt1087PublicKey</code>s and <code>Ntru1087PrivateKey</code>s.
* @throws NoSuchAlgorithmException
* @throws InvalidCipherTextException
* @throws GeneralSecurityException
*/
@Override
public byte[] decrypt(byte[] data, PublicKey publicKey, PrivateKey privateKey) throws NoSuchAlgorithmException, InvalidCipherTextException {
public byte[] decrypt(byte[] data, PublicKey publicKey, PrivateKey privateKey) throws GeneralSecurityException {
if (data == null)
return null;

Some files were not shown because too many files have changed in this diff Show More