Esempio n. 1
0
/* Merge signatures from userid in fkey (which is keyfile) at keypos with
 * userid from fring (which is ringfile) at ringpos, appending result to out.
 */
static int mergesigs(FILE * fkey, char *keyfile, long keypos, FILE * fring,
		     char *ringfile, long *pringpos, FILE * out)
{
    long ringuseridpos, ringpos;
    int ringpktlen, keypktlen;
    int status;
    byte ctb;
    int copying;
    word32 rstamp, kstamp, xstamp;
    byte keyID[KEYFRAGSIZE];
    char userid[256];

    /* First, copy the userid packet itself, plus any comments or ctrls */
    ringuseridpos = ringpos = *pringpos;
    fseek(fring, ringpos, SEEK_SET);
    (void) readkeypacket(fring, FALSE, &ctb, NULL, userid, NULL, NULL,
			 NULL, NULL, NULL, NULL, NULL, NULL);
    PascalToC(userid);
    ringpktlen = ftell(fring) - ringpos;
    copyfilepos(fring, out, ringpktlen, ringpos);
    for (;;) {
	ringpos = ftell(fring);
	status = nextkeypacket(fring, &ctb);
	if (status < 0 || is_key_ctb(ctb) || ctb == CTB_USERID ||
	    is_ctb_type(ctb, CTB_SKE_TYPE))
	    break;
	ringpktlen = ftell(fring) - ringpos;
	copyfilepos(fring, out, ringpktlen, ringpos);
    }
    fseek(fring, ringpos, SEEK_SET);

    /* Now, ringpos points just past userid packet and ctrl packet. */
    /* Advance keypos to the analogous location. */
    fseek(fkey, keypos, SEEK_SET);
    (void) nextkeypacket(fkey, &ctb);
    for (;;) {
	keypos = ftell(fkey);
	status = nextkeypacket(fkey, &ctb);
	if (status < 0 || is_key_ctb(ctb) || ctb == CTB_USERID ||
	    is_ctb_type(ctb, CTB_SKE_TYPE))
	    break;
    }
    fseek(fkey, keypos, SEEK_SET);

    /* Second, copy all keyfile signatures that aren't in ringfile.
     */

    copying = FALSE;
    for (;;) {
	/* Read next sig from keyfile; see if it is in ringfile;
	 * if it is not a signature, ignore it,
	 * if it is absent from ringfile, copy it,
	 * if it is present, and the timestamp is not newer, ignore it,
	 * if present and newer, replace old with new.
	 * Loop till hit a new key or userid in keyfile, or EOF.
	 */
	keypos = ftell(fkey);
	status = readkeypacket(fkey, FALSE, &ctb, (byte *) & kstamp,
			       NULL, NULL, NULL,
			       NULL, NULL, NULL, NULL, keyID, NULL);
	if (status == -3)	/* unrecoverable error: bad packet
				   length etc. */
	    return status;
	keypktlen = ftell(fkey) - keypos;
	if (status == -1 || is_key_ctb(ctb) || ctb == CTB_USERID)
	    break;		/* EOF or next key/userid */
	if (status < 0)
	    continue;		/* bad packet, skip it */
	if (is_ctb_type(ctb, CTB_SKE_TYPE)) {
	    long sig_pos;
	    int sig_len;
	    /* Set copying true if signature is not in the ringfile */
	    copying = (getpubusersig(ringfile, ringuseridpos,
				     keyID, (byte *) & rstamp,
				     &sig_pos,
				     &sig_len) < 0);
	    if (!copying) {
		long save_pos = ftell(fkey);
		fseek(fkey, keypos + 6, SEEK_SET);
		fread(&kstamp, 1, SIZEOF_TIMESTAMP, fkey);
		fseek(fkey, save_pos, SEEK_SET);
		convert_byteorder((byte *) & kstamp, SIZEOF_TIMESTAMP);
		if (verbose)
		    fprintf(pgpout, "ring: %lx  key: %lx\n", rstamp, kstamp);
		if (kstamp > rstamp) {	/* Update, Maybe */
		    char *signator;
		    if ((signator = user_from_keyID(keyID)) == NULL) {
			fprintf(pgpout,
	       LANG("Replacing signature from keyID %s on userid \"%s\"\n"),
				keyIDstring(keyID), LOCAL_CHARSET(userid));
			/* No pubkey for KeyID, no update! */
		    } else {
			long save_keypos;
			long save_ringpos;
			long KeyIDpos;
			int KeyIDlen;
			byte sigClass;
			fprintf(pgpout,
				LANG("Verifying signature from %s\n"),
				LOCAL_CHARSET(signator));
			fprintf(pgpout, LANG("on userid \"%s\"\n"),
				LOCAL_CHARSET(userid));
			save_keypos = ftell(fkey);
			save_ringpos = ftell(fring);
			status = getpublickey(GPK_GIVEUP, ringfile,
					      &KeyIDpos, &KeyIDlen, NULL,
					      NULL, (byte *) userid, NULL,
					      NULL);
			if (!status)
			    status = check_key_sig(fring,
						   KeyIDpos, KeyIDlen,
						   userid, fkey, keypos,
						   ringfile, signator,
						   (byte *) & xstamp,
						   &sigClass);
			PascalToC(userid);
			PascalToC(signator);
			if (!status) {
			    fprintf(pgpout,
				    LANG("Replacing signature from %s\n"),
				    LOCAL_CHARSET(signator));
			    fprintf(pgpout,
				    LANG("on userid \"%s\"\n"),
				    LOCAL_CHARSET(userid));
			    sig_list_add(sig_pos);
			    ++newsigs;
			    copying = 1;
			} else
			    fprintf(pgpout, LANG("Verification Failed\n"));
			fseek(fring, save_ringpos, SEEK_SET);
			fseek(fkey, save_keypos, SEEK_SET);
		    }
		}
	    } else {
		char *signator;
		if ((signator = user_from_keyID(keyID)) == NULL)
		    fprintf(pgpout,
		       LANG("New signature from keyID %s on userid \"%s\"\n"),
			    keyIDstring(keyID), LOCAL_CHARSET(userid));
		else {
		    fprintf(pgpout,
			    LANG("New signature from %s\n"),
			    LOCAL_CHARSET(signator));
		    fprintf(pgpout,
			    LANG("on userid \"%s\"\n"), LOCAL_CHARSET(userid));
		}
		++newsigs;
		if (batchmode)
		    show_update(keyIDstring(mykeyID));
	    }
	}
	if (copying && is_ctb_type(ctb, CTB_SKE_TYPE)) {
	    copyfilepos(fkey, out, keypktlen, keypos);
	    if (publickey)
		write_trust(out, KC_SIGTRUST_UNDEFINED);
	}
    }

    /* Third, for all ring sig's which are not replaced, copy to output */
    fseek(fring, ringpos, SEEK_SET);
    for (;;) {
	ringpos = ftell(fring);
	if (sig_list_find(ringpos)) {
	    /* skip signature packet */
	    nextkeypacket(fring, &ctb);
	    ringpos = ftell(fring);
	    /* skip trust packet, if present */
	    if (nextkeypacket(fring, &ctb) < 0 || ctb != CTB_KEYCTRL)
		fseek(fring, ringpos, SEEK_SET);
	    continue;
	}
	status = nextkeypacket(fring, &ctb);
	ringpktlen = ftell(fring) - ringpos;
	if (status < 0 || is_key_ctb(ctb) || ctb == CTB_USERID)
	    break;
	copyfilepos(fring, out, ringpktlen, ringpos);
    }				/* End of loop for each sig in ringfile */
    sig_list_clear();
    fseek(fring, ringpos, SEEK_SET);
    *pringpos = ringpos;
    return 0;
}				/* mergesigs */
Esempio n. 2
0
static int
handle_device (libusb_device *dev, struct libusb_config_descriptor *cfg, int itfnum, const struct libusb_interface_descriptor *alt)
{
	libusb_device_handle *devh;
	int res, retval;

	retval = -1;

	if (libusb_open (dev, &devh) < 0) {
		g_warning ("Can't open device");
		goto bail;
	}
	libusb_detach_kernel_driver (devh, itfnum);

	res = libusb_claim_interface (devh, itfnum);
	if (res < 0) {
		g_warning ("Can't claim interface %d", itfnum);
		goto bail;
	}

	if (option_get_master != FALSE) {
		if (show_master (devh, itfnum) == FALSE)
			goto bail;
		retval = 0;
	}

	if (option_master != NULL) {
		if (strcmp (option_master, "auto") == 0) {
			g_free (option_master);
			option_master = get_host_bdaddr ();
			if (option_master == NULL) {
				g_warning ("Can't get bdaddr from default device");
				retval = -1;
				goto bail;
			}
		}
	} else {
		option_master = get_host_bdaddr ();
		if (option_master == NULL) {
			g_warning ("Can't get bdaddr from default device");
			retval = -1;
			goto bail;
		}
	}

	if (option_store_info != FALSE) {
		sdp_record_t *rec;
		char *device;
		bdaddr_t dst, src;

		device = get_bdaddr (devh, itfnum);
		if (device == NULL) {
			retval = -1;
			goto bail;
		}

		rec = record_from_string (PS3_PNP_RECORD);
		store_record(option_master, device, rec);
		write_trust(option_master, device, "[all]", TRUE);
		store_device_id(option_master, device, 0xffff, 0x054c, 0x0268, 0);
		str2ba(option_master, &src);
		str2ba(device, &dst);
		write_device_profiles(&src, &dst, "");
		write_device_name(&src, &dst, "PLAYSTATION(R)3 Controller");
		sdp_record_free(rec);

		if (set_master_bdaddr (devh, itfnum, option_master) == FALSE) {
			retval = -1;
			goto bail;
		}
	}

bail:
	libusb_release_interface (devh, itfnum);
	res = libusb_attach_kernel_driver(devh, itfnum);
	if (res < 0) {
		//FIXME sometimes the kernel tells us ENOENT, but succeeds anyway...
		g_warning ("Reattaching the driver failed: %d", res);
	}
	if (devh != NULL)
		libusb_close (devh);

	return retval;
}
Esempio n. 3
0
/* Merge key from fkey (which is keyfile) at keypos with key from
 * fring (which is ringfile) at ringpos, appending result to out.
 */
static int mergekeys(FILE * fkey, char *keyfile, long keypos, FILE * fring,
		     char *ringfile, long *pringpos, FILE * out)
{
    long ringkeypos, keykeypos, ringpos;
    int ringpktlen, keypktlen;
    int status;
    byte ctb;
    int copying;
    boolean ring_compromise = FALSE;
    byte userid[256];

    /* First, copy the key packet itself, plus any comments or ctrls */
    ringkeypos = ringpos = *pringpos;
    fseek(fring, ringpos, SEEK_SET);
    (void) nextkeypacket(fring, &ctb);
    ringpktlen = ftell(fring) - ringpos;
    copyfilepos(fring, out, ringpktlen, ringpos);
    for (;;) {
	ringpos = ftell(fring);
	status = nextkeypacket(fring, &ctb);
	if (status < 0 || is_key_ctb(ctb) || ctb == CTB_USERID)
	    break;
	if (is_ctb_type(ctb, CTB_SKE_TYPE))
	    ring_compromise = TRUE;	/* compromise cert on keyring */
	ringpktlen = ftell(fring) - ringpos;
	copyfilepos(fring, out, ringpktlen, ringpos);
    }
    fseek(fring, ringpos, SEEK_SET);

    /* Now, ringpos points just past key packet and ctrl packet. */
    /* Advance keypos to the analogous location. */
    fseek(fkey, keypos, SEEK_SET);
    keykeypos = keypos;
    (void) nextkeypacket(fkey, &ctb);
    keypktlen = ftell(fkey) - keypos;	/* for check_key_sig() */
    for (;;) {
	keypos = ftell(fkey);
	status = nextkeypacket(fkey, &ctb);
	if (status < 0 || ctb == CTB_USERID || is_ctb_type(ctb, CTB_SKE_TYPE))
	    break;
    }
    if (!ring_compromise && is_ctb_type(ctb, CTB_SKE_TYPE)) {
	/* found a compromise cert on keyfile that is not in ringfile */
	word32 timestamp;
	byte sig_class;
	int cert_pktlen;

	cert_pktlen = ftell(fkey) - keypos;
	if (check_key_sig(fkey, keykeypos, keypktlen,
			  (char *) userid, fkey, keypos,
			  ringfile, (char *) userid, (byte *) & timestamp,
			  &sig_class) == 0 &&
	    sig_class == KC_SIGNATURE_BYTE) {
	    PascalToC((char *) userid);
	    fprintf(pgpout, LANG("Key revocation certificate from \"%s\".\n"),
		    LOCAL_CHARSET((char *) userid));
	    copyfilepos(fkey, out, cert_pktlen, keypos);
	    /* Show updates */
	    if (batchmode)
		show_key(fring, *pringpos, SHOW_CHANGE);
	    ++newrvks;
	} else
	    fprintf(pgpout,
     LANG("\n\007WARNING:  File '%s' contains bad revocation certificate.\n"),
		    keyfile);
    }
    fseek(fkey, keypos, SEEK_SET);

    /* Second, copy all keyfile userid's plus signatures that aren't
     * in ringfile.
     */

    copying = FALSE;
    for (;;) {
	/* Read next userid from keyfile; see if it is in ringfile;
	 * set copying true/false accordingly.  If copying is true
	 * and it is a userid or a signature, copy it.  Loop till hit
	 * a new key in keyfile, or EOF.
	 */
	keypos = ftell(fkey);
	status = readkeypacket(fkey, FALSE, &ctb, NULL, (char *) userid, NULL,
			       NULL, NULL, NULL, NULL, NULL, NULL, NULL);
	if (status == -3) /* unrecoverable error: bad packet length etc. */
	    return status;
	keypktlen = ftell(fkey) - keypos;
	if (status == -1 || is_key_ctb(ctb))
	    break;		/* EOF or next key */
	if (status < 0)
	    continue;		/* bad packet, skip it */
	if (ctb == CTB_USERID) {
	    long userid_pos;
	    int userid_len;
	    PascalToC((char *) userid);
	    /* Set copying true if userid is not in the ringfile */
	    copying = (getpubuserid(ringfile, ringkeypos, userid, &userid_pos,
				    &userid_len, TRUE) < 0);
	    if (copying) {
		putc('\n', pgpout);
		fprintf(pgpout, LANG("New userid: \"%s\".\n"),
			LOCAL_CHARSET((char *) userid));
		fprintf(pgpout,
			LANG("\nWill be added to the following key:\n"));
		show_key(fring, *pringpos, 0);
		fprintf(pgpout, LANG("\nAdd this userid (y/N)? "));
		if (batchmode || getyesno('n')) {
		    ++newids;
		    /* Show an update string */
		    if (batchmode) {
			fprintf(pgpout, "\n");
			show_key(fring, *pringpos, SHOW_CHANGE);
		    }
		} else {
		    copying = FALSE;
		}
	    }
	}
	if (copying) {
	    if (ctb == CTB_USERID || is_ctb_type(ctb, CTB_SKE_TYPE)) {
		copyfilepos(fkey, out, keypktlen, keypos);
		if (publickey) {
		    if (is_ctb_type(ctb, CTB_SKE_TYPE))
			write_trust(out, KC_SIGTRUST_UNDEFINED);
		    else
			write_trust(out, KC_LEGIT_UNKNOWN);
		}
	    }
	}
    }

    /* Third, for all ring userid's, if not in keyfile, copy the userid
     * plus its dependant signatures.
     */
    fseek(fring, ringpos, SEEK_SET);
    /* Grab the keyID here */
    readkeypacket(fring, FALSE, &ctb, NULL, (char *) userid, NULL, NULL,
		  NULL, NULL, NULL, NULL, NULL, NULL);
    fseek(fring, ringpos, SEEK_SET);
    for (;;) {
	ringpos = ftell(fring);
	status = readkeypacket(fring, FALSE, &ctb, NULL,
			       (char *) userid, NULL, NULL,
			       NULL, NULL, NULL, NULL, NULL, NULL);
	ringpktlen = ftell(fring) - ringpos;
	if (status == -3)
	    return status;
	if (status == -1 || is_key_ctb(ctb))
	    break;
	if (ctb == CTB_USERID) {
	    long userid_pos;
	    int userid_len;
	    /* See if there is a match in keyfile */
	    PascalToC((char *) userid);
	    /* don't use substring match (exact_match = TRUE) */
	    if (getpubuserid(keyfile, keykeypos, userid,
			     &userid_pos, &userid_len, TRUE) >= 0) {
		if ((status = mergesigs(fkey, keyfile, userid_pos,
					fring, ringfile, &ringpos, out)) < 0)
		    return status;
		copying = FALSE;
	    } else {
		copying = TRUE;
	    }
	}
	if (copying) {
	    /* Copy ringfile userid and sigs to out */
	    copyfilepos(fring, out, ringpktlen, ringpos);
	}
    }				/* End of loop for each key in ringfile */
    fseek(fring, ringpos, SEEK_SET);
    *pringpos = ringpos;
    return 0;
}				/* mergekeys */