aboutsummaryrefslogtreecommitdiffstats
path: root/g10/ringedit.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--g10/ringedit.c141
1 files changed, 139 insertions, 2 deletions
diff --git a/g10/ringedit.c b/g10/ringedit.c
index 141d8cf7f..adba3db0b 100644
--- a/g10/ringedit.c
+++ b/g10/ringedit.c
@@ -77,6 +77,7 @@ static int keyring_search( PACKET *pkt, KBPOS *kbpos, IOBUF iobuf );
static int keyring_search2( PUBKEY_FIND_INFO info, KBPOS *kbpos,
const char *fname);
static int keyring_read( KBPOS *kbpos, KBNODE *ret_root );
+static int keyring_enum( KBPOS *kbpos, KBNODE *ret_root );
static int keyring_copy( KBPOS *kbpos, int mode, KBNODE root );
@@ -297,6 +298,78 @@ read_keyblock( KBPOS *kbpos, KBNODE *ret_root )
return keyring_read( kbpos, ret_root );
}
+
+/****************
+ * This functions can be used to read trough a complete keyring.
+ * Mode is: 0 = open
+ * 1 = read
+ * 2 = close
+ * all others are reserved!
+ * Note that you do not need a search prior to call this function,
+ * only handle is needed.
+ * NOTE: It is not alloed to do an insert/update/delte with this
+ * keyblock, if you want to do this, user search/read!
+ */
+int
+enum_keyblocks( int mode, KBPOS *kbpos, KBNODE *ret_root )
+{
+ int rc = 0;
+ RESTBL *rentry;
+
+ if( !mode || mode == 100 ) {
+ int i;
+ kbpos->fp = NULL;
+ if( !mode )
+ i = 0;
+ else
+ i = kbpos->resno+1;
+ for(; i < MAX_RESOURCES; i++ )
+ if( resource_table[i].used && !resource_table[i].secret )
+ break;
+ if( i == MAX_RESOURCES )
+ return -1; /* no resources */
+ kbpos->resno = i;
+ rentry = check_pos( kbpos );
+ kbpos->fp = iobuf_open( rentry->fname );
+ if( !kbpos->fp ) {
+ log_error("can't open '%s'\n", rentry->fname );
+ return G10ERR_OPEN_FILE;
+ }
+ kbpos->pkt = NULL;
+ }
+ else if( mode == 1 ) {
+ int cont;
+ do {
+ cont = 0;
+ if( !kbpos->fp )
+ return G10ERR_GENERAL;
+ rc = keyring_enum( kbpos, ret_root );
+ if( rc == -1 ) {
+ assert( !kbpos->pkt );
+ rentry = check_pos( kbpos );
+ assert(rentry);
+ /* close */
+ enum_keyblocks(2, kbpos, ret_root );
+ /* and open the next one */
+ rc = enum_keyblocks(100, kbpos, ret_root );
+ if( !rc )
+ cont = 1;
+ }
+ } while(cont);
+ }
+ else if( kbpos->fp ) {
+ iobuf_close( kbpos->fp );
+ kbpos->fp = NULL;
+ /* release pending packet */
+ free_packet( kbpos->pkt );
+ m_free( kbpos->pkt );
+ }
+ return rc;
+}
+
+
+
+
/****************
* Insert the keyblock described by ROOT into the keyring described
* by KBPOS. This actually appends the data to the keyfile.
@@ -551,9 +624,8 @@ keyring_read( KBPOS *kbpos, KBNODE *ret_root )
if( rc )
release_kbnode( root );
- else {
+ else
*ret_root = root;
- }
free_packet( pkt );
m_free( pkt );
iobuf_close(a);
@@ -561,6 +633,69 @@ keyring_read( KBPOS *kbpos, KBNODE *ret_root )
}
+static int
+keyring_enum( KBPOS *kbpos, KBNODE *ret_root )
+{
+ PACKET *pkt;
+ int rc;
+ RESTBL *rentry;
+ KBNODE root = NULL;
+ int in_cert = 0;
+
+ if( !(rentry=check_pos(kbpos)) )
+ return G10ERR_GENERAL;
+
+ if( kbpos->pkt ) {
+ root = new_kbnode( kbpos->pkt );
+ kbpos->pkt = NULL;
+ }
+
+ pkt = m_alloc( sizeof *pkt );
+ init_packet(pkt);
+ while( (rc=parse_packet(kbpos->fp, pkt)) != -1 ) {
+ if( rc ) { /* ignore errors */
+ if( rc != G10ERR_UNKNOWN_PACKET ) {
+ log_error("read_keyblock: read error: %s\n", g10_errstr(rc) );
+ rc = G10ERR_INV_KEYRING;
+ goto ready;
+ }
+ free_packet( pkt );
+ continue;
+ }
+ /* make a linked list of all packets */
+ switch( pkt->pkttype ) {
+ case PKT_PUBLIC_CERT:
+ case PKT_SECRET_CERT:
+ if( in_cert ) { /* store this packet */
+ kbpos->pkt = pkt;
+ pkt = NULL;
+ goto ready;
+ }
+ in_cert = 1;
+ default:
+ if( !root )
+ root = new_kbnode( pkt );
+ else
+ add_kbnode( root, new_kbnode( pkt ) );
+ pkt = m_alloc( sizeof *pkt );
+ init_packet(pkt);
+ break;
+ }
+ }
+ ready:
+ if( rc == -1 && root )
+ rc = 0;
+
+ if( rc )
+ release_kbnode( root );
+ else
+ *ret_root = root;
+ free_packet( pkt );
+ m_free( pkt );
+ return rc;
+}
+
+
/****************
* Peromf insert/delete/update operation.
@@ -579,6 +714,8 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root )
if( !(rentry = check_pos( kbpos )) )
return G10ERR_GENERAL;
+ if( kbpos->fp )
+ BUG(); /* not allowed with such a handle */
/* open the source file */
fp = iobuf_open( rentry->fname );