/****************************************************************************** * rangeset.c * * Creation, maintenance and automatic destruction of per-domain sets of * numeric ranges. * * Copyright (c) 2005, K A Fraser */ #include #include #include /* An inclusive range [s,e] and pointer to next range in ascending order. */ struct range { struct list_head list; unsigned long s, e; }; struct rangeset { /* Owning domain and threaded list of rangesets. */ struct list_head rangeset_list; struct domain *domain; /* Ordered list of ranges contained in this set, and protecting lock. */ struct list_head range_list; spinlock_t lock; /* Pretty-printing name. */ char name[32]; /* RANGESETF flags. */ unsigned int flags; }; /***************************** * Private range functions hide the underlying linked-list implemnetation. */ /* Find highest range lower than or containing s. NULL if no such range. */ static struct range *find_range( struct rangeset *r, unsigned long s) { struct range *x = NULL, *y; list_for_each_entry ( y, &r->range_list, list ) { if ( y->s > s ) break; x = y; } return x; } /* Return the lowest range in the set r, or NULL if r is empty. */ static struct range *first_range( struct rangeset *r) { if ( list_empty(&r->range_list) ) return NULL; return list_entry(r->range_list.next, struct range, list); } /* Return range following x in ascending order, or NULL if x is the highest. */ static struct range *next_range( struct rangeset *r, struct range *x) { if ( x->list.next == &r->range_list ) return NULL; return list_entry(x->list.next, struct range, list); } /* Insert range y after range x in r. Insert as first range if x is NULL. */ static void insert_range( struct rangeset *r, struct range *x, struct range *y) { list_add(&y->list, (x != NULL) ? &x->list : &r->range_list); } /* Remove a range from its list and free it. */ static void destroy_range( struct range *x) { list_del(&x->list); xfree(x); } /***************************** * Core public functions */ int rangeset_add_range( struct rangeset *r, unsigned long s, unsigned long e) { struct range *x, *y; int rc = 0; ASSERT(s <= e); spin_lock(&r->lock); x = find_range(r, s); y = find_range(r, e); if ( x == y ) { if ( (x == NULL) || ((x->e < s) && ((x->e + 1) != s)) ) { x = xmalloc(struct range); if ( x == NULL ) { rc = -ENOMEM; goto out; } x->s = s; x->e = e; insert_range(r, y, x); } else if ( x->e < e ) x->e = e; } else { if ( x == NULL ) { x = first_range(r); x->s = s; } else if ( (x->e < s) && ((x->e + 1) != s) ) { x = next_range(r, x); x->s = s; } x->e = (y->e > e) ? y->e : e; for ( ; ; ) { y = next_range(r, x); if ( (y == NULL) || (y->e > x->e) ) break; destroy_range(y); } } y = next_range(r, x); if ( (y != NULL) && ((x->e + 1) == y->s) ) { x->e = y->e; destroy_range(y); } out: spin_unlock(&r->lock); return rc; } int rangeset_remove_range( struct rangeset *r, unsigned long s, unsigned long e) { struct range *x, *y, *t; int rc = 0; ASSERT(s <= e); spin_lock(&r->lock); x = find_range(r, s); y = find_range(r, e); if ( x == y ) { if ( (x == NULL) || (x->e < s) ) goto out; if ( (x->s < s) && (x->e > e) ) { y = xmalloc(struct range); if ( y == NULL ) { rc = -ENOMEM; goto out; } y->s = e + 1; y->e = x->e; x->e = s - 1; insert_range(r, x, y); } else if ( (x->s == s) && (x->e <= e) ) destroy_range(x); else if ( x->s == s ) x->s = e + 1; else if ( x->e <= e ) x->e = s - 1; } else { if ( x == NULL ) x = first_range(r); if ( x->s < s ) { x->e = s - 1; x = next_range(r, x); } while ( x != y ) { t = x; x = next_range(r, x); destroy_range(t); } x->s = e + 1; if ( x->s > x->e ) destroy_range(x); } out: spin_unlock(&r->lock); return rc; } int rangeset_contains_range( struct rangeset *r, unsigned long s, unsigned long e) { struct range *x; int contains; ASSERT(s <= e); spin_lock(&r->lock); x = find_range(r, s); contains = (x && (x->e >= e)); spin_unlock(&r->lock); return contains; } int rangeset_add_singleton( struct rangeset *r, unsigned long s) { return rangeset_add_range(r, s, s); } int rangeset_remove_singleton( struct rangeset *r, unsigned long s) { return rangeset_remove_range(r, s, s); } int rangeset_contains_singleton( struct rangeset *r, unsigned long s) { return rangeset_contains_range(r, s, s); } int rangeset_is_empty( struct rangeset *r) { return list_empty(&r->range_list); } struct rangeset *rangeset_new( struct domain *d, char *name, unsigned int flags) { struct rangeset *r; r = xmalloc(struct rangeset); if ( r == NULL ) return NULL; spin_lock_init(&r->lock); INIT_LIST_HEAD(&r->range_list); BUG_ON(flags & ~RANGESETF_prettyprint_hex); r->flags = flags; if ( name != NULL ) { strlcpy(r->name, name, sizeof(r->name)); } else { snprintf(r->name, sizeof(r->name), "(no name)"); } if ( (r->domain = d) != NULL ) { spin_lock(&d->rangesets_lock); list_add(&r->rangeset_list, &d->rangesets); spin_unlock(&d->rangesets_lock); } return r; } void rangeset_destroy( struct rangeset *r) { struct range *x; if ( r == NULL ) return; if ( r->domain != NULL ) { spin_lock(&r->domain->rangesets_lock); list_del(&r->rangeset_list); spin_unlock(&r->domain->rangesets_lock); } while ( (x = first_range(r)) != NULL ) destroy_range(x); xfree(r); } void rangeset_domain_initialise( struct domain *d) { INIT_LIST_HEAD(&d->rangesets); spin_lock_init(&d->rangesets_lock); } void rangeset_domain_destroy( struct domain *d) { struct rangeset *r; while ( !list_empty(&d->rangesets) ) { r = list_entry(d->rangesets.next, struct rangeset, rangeset_list); BUG_ON(r->domain != d); r->domain = NULL; list_del(&r->rangeset_list); rangeset_destroy(r); } } /***************************** * Pretty-printing functions */ static void print_limit(struct rangeset *r, unsigned long s) { printk((r->flags & RANGESETF_prettyprint_hex) ? "%lx" : "%lu", s); } void rangeset_printk( struct rangeset *r) { int nr_printed = 0; struct range *x; spin_lock(&r->lock); printk("%-10s {", r->name); for ( x = first_range(r); x != NULL; x = next_range(r, x) ) { if ( nr_printed++ ) printk(","); printk(" "); print_limit(r, x->s); if ( x->s != x->e ) { printk("-"); print_limit(r, x->e); } } printk(" }"); spin_unlock(&r->lock); } void rangeset_domain_printk( struct domain *d) { struct rangeset *r; printk("Rangesets belonging to domain %u:\n", d->domain_id); spin_lock(&d->rangesets_lock); if ( list_empty(&d->rangesets) ) printk(" None\n"); list_for_each_entry ( r, &d->rangesets, rangeset_list ) { printk(" "); rangeset_printk(r); printk("\n"); } spin_unlock(&d->rangesets_lock); } f='#n122'>122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
<html>
<head></head>
<body>
<h2>2.8</h2>
<ul>
<li>So many bugs have been fixed in this release that we focus on the main new features</li>
<li>Key edit: awesome new design, key revocation</li>
<li>Key import: awesome new design, secure keyserver connections via hkps, keyserver resolving via DNS SRV records</li>
<li>New first time screen</li>
<li>New key creation screen: autocompletion of name and email based on your personal Android accounts</li>
<li>File encryption: awesome new design, support for encrypting multiple files</li>
<li>New icons to show status of key (by Brennan Novak)</li>
<li>Important bug fix: Importing of large key collections from a file is now possible</li>
<li>Notification showing cached passphrases</li>
<li>Keys are connected to Android's contacts</li>
</ul>
<p>This release wouldn't be possible without the work of Vincent Breitmoser (GSoC 2014), mar-v-in (GSoC 2014), Daniel Albert, Art O Cathain, Daniel Haß, Tim Bray, Thialfihar</p>

<h2>2.7</h2>
<ul>
<li>Purple! (Dominik, Vincent)</li>
<li>New key view design (Dominik, Vincent)</li>
<li>New flat Android buttons (Dominik, Vincent)</li>
<li>API fixes (Dominik)</li>
<li>Keybase.io import (Tim Bray)</li>
</ul>
<h2>2.6.1</h2>
<ul>
<li>Some fixes for regression bugs</li>
</ul>
<h2>2.6</h2>
<ul>
<li>Key certifications (thanks to Vincent Breitmoser)</li>
<li>Support for GnuPG partial secret keys (thanks to Vincent Breitmoser)</li>
<li>New design for signature verification</li>
<li>Custom key length (thanks to Greg Witczak)</li>
<li>Fix share-functionality from other apps</li>
</ul>
<h2>2.5</h2>
<ul>
<li>Fix decryption of symmetric pgp messages/files</li>
<li>Refactored key edit screen (thanks to Ash Hughes)</li>
<li>New modern design for encrypt/decrypt screens</li>
<li>OpenPGP API version 3 (multiple api accounts, internal fixes, key lookup)</li>
</ul>
<h2>2.4</h2>
<p>Thanks to all applicants of Google Summer of Code 2014 who made this release feature rich and bug free!
Besides several small patches, a notable number of patches are made by the following people (in alphabetical order):
Daniel Hammann, Daniel Haß, Greg Witczak, Miroojin Bakshi, Nikhil Peter Raj, Paul Sarbinowski, Sreeram Boyapati, Vincent Breitmoser.</p>
<ul>
<li>New unified key list</li>
<li>Colorized key fingerprint</li>
<li>Support for keyserver ports</li>
<li>Deactivate possibility to generate weak keys</li>
<li>Much more internal work on the API</li>
<li>Certify user ids</li>
<li>Keyserver query based on machine-readable output</li>
<li>Lock navigation drawer on tablets</li>
<li>Suggestions for emails on creation of keys</li>
<li>Search in public key lists</li>
<li>And much more improvements and fixes…</li>
</ul>
<h2>2.3.1</h2>
<ul>
<li>Hotfix for crash when upgrading from old versions</li>
</ul>
<h2>2.3</h2>
<ul>
<li>Remove unnecessary export of public keys when exporting secret key (thanks to Ash Hughes)</li>
<li>Fix setting expiry dates on keys (thanks to Ash Hughes)</li>
<li>More internal fixes when editing keys (thanks to Ash Hughes)</li>
<li>Querying keyservers directly from the import screen</li>
<li>Fix layout and dialog style on Android 2.2-3.0</li>
<li>Fix crash on keys with empty user ids</li>
<li>Fix crash and empty lists when coming back from signing screen</li>
<li>Bouncy Castle (cryptography library) updated from 1.47 to 1.50 and build from source</li>
<li>Fix upload of key from signing screen</li>
</ul>
<h2>2.2</h2>
<ul>
<li>New design with navigation drawer</li>
<li>New public key list design</li>
<li>New public key view</li>
<li>Bug fixes for importing of keys</li>
<li>Key cross-certification (thanks to Ash Hughes)</li>
<li>Handle UTF-8 passwords properly (thanks to Ash Hughes)</li>
<li>First version with new languages (thanks to the contributors on Transifex)</li>
<li>Sharing of keys via QR Codes fixed and improved</li>
<li>Package signature verification for API</li>
</ul>
<h2>2.1.1</h2>
<ul>
<li>API Updates, preparation for K-9 Mail integration</li>
</ul>
<h2>2.1</h2>
<ul>
<li>Lots of bug fixes</li>
<li>New API for developers</li>
<li>PRNG bug fix by Google</li>
</ul>
<h2>2.0</h2>
<ul>
<li>Complete redesign</li>
<li>Share public keys via qr codes, nfc beam</li>
<li>Sign keys</li>
<li>Upload keys to server</li>
<li>Fixes import issues</li>
<li>New AIDL API</li>
</ul>
<h2>1.0.8</h2>
<ul>
<li>Basic keyserver support</li>
<li>App2sd</li>
<li>More choices for passphrase cache: 1, 2, 4, 8, hours</li>
<li>Translations: Norwegian (thanks, Sander Danielsen), Chinese (thanks, Zhang Fredrick)</li>
<li>Bugfixes</li>
<li>Optimizations</li>
</ul>
<h2>1.0.7</h2>
<ul>
<li>Fixed problem with signature verification of texts with trailing newline</li>
<li>More options for passphrase cache time to live (20, 40, 60 mins)</li>
</ul>
<h2>1.0.6</h2>
<ul>
<li>Account adding crash on Froyo fixed</li>
<li>Secure file deletion</li>
<li>Option to delete key file after import</li>
<li>Stream encryption/decryption (gallery, etc.)</li>
<li>New options (language, force v3 signatures)</li>
<li>Interface changes</li>
<li>Bugfixes</li>
</ul>
<h2>1.0.5</h2>
<ul>
<li>German and Italian translation</li>
<li>Much smaller package, due to reduced BC sources</li>
<li>New preferences GUI</li>
<li>Layout adjustment for localization</li>
<li>Signature bugfix</li>
</ul>
<h2>1.0.4</h2>
<ul>
<li>Fixed another crash caused by some SDK bug with query builder</li>
</ul>
<h2>1.0.3</h2>
<ul>
<li>Fixed crashes during encryption/signing and possibly key export</li>
</ul>
<h2>1.0.2</h2>
<ul>
<li>Filterable key lists</li>
<li>Smarter pre-selection of encryption keys</li>
<li>New Intent handling for VIEW and SEND, allows files to be encrypted/decrypted out of file managers</li>
<li>Fixes and additional features (key preselection) for K-9 Mail, new beta build available</li>
</ul>
<h2>1.0.1</h2>
<ul>
<li>GMail account listing was broken in 1.0.0, fixed again</li>
</ul>
<h2>1.0.0</h2>
<ul>
<li>K-9 Mail integration, APG supporting beta build of K-9 Mail</li>
<li>Support of more file managers (including ASTRO)</li>
<li>Slovenian translation</li>
<li>New database, much faster, less memory usage</li>
<li>Defined Intents and content provider for other apps</li>
<li>Bugfixes</li>
</ul>
</body>
</html>