Merge branch 'master' of git+ssh://taler.net/var/git/mint
This commit is contained in:
commit
4c80119b30
@ -52,18 +52,6 @@ json_t *
|
|||||||
TALER_json_from_abs (struct GNUNET_TIME_Absolute stamp);
|
TALER_json_from_abs (struct GNUNET_TIME_Absolute stamp);
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert a signature (with purpose) to a JSON object representation.
|
|
||||||
*
|
|
||||||
* @param purpose purpose of the signature
|
|
||||||
* @param signature the signature
|
|
||||||
* @return the JSON reporesentation of the signature with purpose
|
|
||||||
*/
|
|
||||||
json_t *
|
|
||||||
TALER_json_from_eddsa_sig (const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose,
|
|
||||||
const struct GNUNET_CRYPTO_EddsaSignature *signature);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert RSA public key to JSON.
|
* Convert RSA public key to JSON.
|
||||||
*
|
*
|
||||||
@ -93,7 +81,8 @@ TALER_json_from_rsa_signature (struct GNUNET_CRYPTO_rsa_Signature *sig);
|
|||||||
* @return json string that encodes @a data
|
* @return json string that encodes @a data
|
||||||
*/
|
*/
|
||||||
json_t *
|
json_t *
|
||||||
TALER_json_from_data (const void *data, size_t size);
|
TALER_json_from_data (const void *data,
|
||||||
|
size_t size);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -132,6 +132,12 @@
|
|||||||
*/
|
*/
|
||||||
#define TALER_SIGNATURE_MERCHANT_REFUND 1102
|
#define TALER_SIGNATURE_MERCHANT_REFUND 1102
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Signature where the merchant confirms that he needs the wire
|
||||||
|
* transfer identifier for a deposit operation.
|
||||||
|
*/
|
||||||
|
#define TALER_SIGNATURE_MERCHANT_DEPOSIT_WTID 1103
|
||||||
|
|
||||||
|
|
||||||
/*********************/
|
/*********************/
|
||||||
/* Wallet signatures */
|
/* Wallet signatures */
|
||||||
@ -300,8 +306,7 @@ struct TALER_DepositRequestPS
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The Merchant's public key. Allows the merchant to later refund
|
* The Merchant's public key. Allows the merchant to later refund
|
||||||
* the transaction. All zeros if nobody is allowed to refund the
|
* the transaction or to inquire about the wire transfer identifier.
|
||||||
* transaction later.
|
|
||||||
*/
|
*/
|
||||||
struct TALER_MerchantPublicKeyP merchant;
|
struct TALER_MerchantPublicKeyP merchant;
|
||||||
|
|
||||||
@ -372,8 +377,7 @@ struct TALER_DepositConfirmationPS
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The Merchant's public key. Allows the merchant to later refund
|
* The Merchant's public key. Allows the merchant to later refund
|
||||||
* the transaction. All zeros if nobody is allowed to refund the
|
* the transaction or to inquire about the wire transfer identifier.
|
||||||
* transaction later.
|
|
||||||
*/
|
*/
|
||||||
struct TALER_MerchantPublicKeyP merchant;
|
struct TALER_MerchantPublicKeyP merchant;
|
||||||
|
|
||||||
@ -791,6 +795,56 @@ struct TALER_MintWireSupportMethodsPS
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Format used to generate the signature on a request to obtain
|
||||||
|
* the wire transfer identifier associated with a deposit.
|
||||||
|
*/
|
||||||
|
struct TALER_DepositTrackPS
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Purpose must be #TALER_SIGNATURE_MERCHANT_DEPOSIT_WTID.
|
||||||
|
*/
|
||||||
|
struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hash over the contract for which this deposit is made.
|
||||||
|
*/
|
||||||
|
struct GNUNET_HashCode h_contract GNUNET_PACKED;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hash over the wiring information of the merchant.
|
||||||
|
*/
|
||||||
|
struct GNUNET_HashCode h_wire GNUNET_PACKED;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merchant-generated transaction ID to detect duplicate
|
||||||
|
* transactions. The merchant must communicate a merchant-unique ID
|
||||||
|
* to the customer for each transaction. Note that different coins
|
||||||
|
* that are part of the same transaction can use the same
|
||||||
|
* transaction ID. The transaction ID is useful for later disputes,
|
||||||
|
* and the merchant's contract offer (@e h_contract) with the
|
||||||
|
* customer should include the offer's term and transaction ID
|
||||||
|
* signed with a key from the merchant.
|
||||||
|
*/
|
||||||
|
uint64_t transaction_id GNUNET_PACKED;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Merchant's public key. The deposit inquiry request is to be
|
||||||
|
* signed by the corresponding private key (using EdDSA).
|
||||||
|
*/
|
||||||
|
struct TALER_MerchantPublicKeyP merchant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The coin's public key. This is the value that must have been
|
||||||
|
* signed (blindly) by the Mint.
|
||||||
|
*/
|
||||||
|
struct TALER_CoinSpendPublicKeyP coin_pub;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GNUNET_NETWORK_STRUCT_END
|
GNUNET_NETWORK_STRUCT_END
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -62,13 +62,20 @@ TALER_MINT_verify_coin_history_ (const char *currency,
|
|||||||
{
|
{
|
||||||
json_t *transaction;
|
json_t *transaction;
|
||||||
struct TALER_Amount amount;
|
struct TALER_Amount amount;
|
||||||
struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
|
struct TALER_CoinSpendSignatureP sig;
|
||||||
|
void *details;
|
||||||
|
size_t details_size;
|
||||||
|
const char *type;
|
||||||
struct MAJ_Specification spec[] = {
|
struct MAJ_Specification spec[] = {
|
||||||
MAJ_spec_amount ("amount",
|
MAJ_spec_amount ("amount",
|
||||||
&amount),
|
&amount),
|
||||||
MAJ_spec_eddsa_signed_purpose ("signature",
|
MAJ_spec_string ("type",
|
||||||
&purpose,
|
&type),
|
||||||
&coin_pub->eddsa_pub),
|
MAJ_spec_fixed_auto ("signature",
|
||||||
|
&sig),
|
||||||
|
MAJ_spec_varsize ("details",
|
||||||
|
&details,
|
||||||
|
&details_size),
|
||||||
MAJ_spec_end
|
MAJ_spec_end
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -81,57 +88,90 @@ TALER_MINT_verify_coin_history_ (const char *currency,
|
|||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
switch (ntohl (purpose->purpose))
|
if (0 == strcasecmp (type,
|
||||||
|
"DEPOSIT"))
|
||||||
{
|
{
|
||||||
case TALER_SIGNATURE_WALLET_COIN_DEPOSIT:
|
const struct TALER_DepositRequestPS *dr;
|
||||||
{
|
struct TALER_Amount dr_amount;
|
||||||
const struct TALER_DepositRequestPS *dr;
|
|
||||||
struct TALER_Amount dr_amount;
|
|
||||||
|
|
||||||
if (ntohl (purpose->size) != sizeof (struct TALER_DepositRequestPS))
|
if (details_size != sizeof (struct TALER_DepositRequestPS))
|
||||||
{
|
|
||||||
GNUNET_break (0);
|
|
||||||
MAJ_parse_free (spec);
|
|
||||||
return GNUNET_SYSERR;
|
|
||||||
}
|
|
||||||
dr = (const struct TALER_DepositRequestPS *) purpose;
|
|
||||||
TALER_amount_ntoh (&dr_amount,
|
|
||||||
&dr->amount_with_fee);
|
|
||||||
if (0 != TALER_amount_cmp (&dr_amount,
|
|
||||||
&amount))
|
|
||||||
{
|
|
||||||
GNUNET_break (0);
|
|
||||||
MAJ_parse_free (spec);
|
|
||||||
return GNUNET_SYSERR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TALER_SIGNATURE_WALLET_COIN_MELT:
|
|
||||||
{
|
{
|
||||||
const struct TALER_RefreshMeltCoinAffirmationPS *rm;
|
GNUNET_break_op (0);
|
||||||
struct TALER_Amount rm_amount;
|
MAJ_parse_free (spec);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
if (ntohl (purpose->size) != sizeof (struct TALER_RefreshMeltCoinAffirmationPS))
|
|
||||||
{
|
|
||||||
GNUNET_break (0);
|
|
||||||
MAJ_parse_free (spec);
|
|
||||||
return GNUNET_SYSERR;
|
|
||||||
}
|
|
||||||
rm = (const struct TALER_RefreshMeltCoinAffirmationPS *) purpose;
|
|
||||||
TALER_amount_ntoh (&rm_amount,
|
|
||||||
&rm->amount_with_fee);
|
|
||||||
if (0 != TALER_amount_cmp (&rm_amount,
|
|
||||||
&amount))
|
|
||||||
{
|
|
||||||
GNUNET_break (0);
|
|
||||||
MAJ_parse_free (spec);
|
|
||||||
return GNUNET_SYSERR;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
dr = (const struct TALER_DepositRequestPS *) details;
|
||||||
default:
|
if (details_size != ntohl (dr->purpose.size))
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
MAJ_parse_free (spec);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_DEPOSIT,
|
||||||
|
&dr->purpose,
|
||||||
|
&sig.eddsa_signature,
|
||||||
|
&coin_pub->eddsa_pub))
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
MAJ_parse_free (spec);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: check sig!
|
||||||
|
TALER_amount_ntoh (&dr_amount,
|
||||||
|
&dr->amount_with_fee);
|
||||||
|
if (0 != TALER_amount_cmp (&dr_amount,
|
||||||
|
&amount))
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
MAJ_parse_free (spec);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (0 == strcasecmp (type,
|
||||||
|
"MELT"))
|
||||||
|
{
|
||||||
|
const struct TALER_RefreshMeltCoinAffirmationPS *rm;
|
||||||
|
struct TALER_Amount rm_amount;
|
||||||
|
|
||||||
|
if (details_size != sizeof (struct TALER_RefreshMeltCoinAffirmationPS))
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
MAJ_parse_free (spec);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
rm = (const struct TALER_RefreshMeltCoinAffirmationPS *) details;
|
||||||
|
if (details_size != ntohl (rm->purpose.size))
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
MAJ_parse_free (spec);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_MELT,
|
||||||
|
&rm->purpose,
|
||||||
|
&sig.eddsa_signature,
|
||||||
|
&coin_pub->eddsa_pub))
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
MAJ_parse_free (spec);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
TALER_amount_ntoh (&rm_amount,
|
||||||
|
&rm->amount_with_fee);
|
||||||
|
if (0 != TALER_amount_cmp (&rm_amount,
|
||||||
|
&amount))
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
MAJ_parse_free (spec);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/* signature not supported, new version on server? */
|
/* signature not supported, new version on server? */
|
||||||
GNUNET_break (0);
|
GNUNET_break_op (0);
|
||||||
MAJ_parse_free (spec);
|
MAJ_parse_free (spec);
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
|
@ -312,6 +312,39 @@ verify_signatures (const struct TALER_MINT_DenomPublicKey *dki,
|
|||||||
&dki->fee_deposit);
|
&dki->fee_deposit);
|
||||||
dr.merchant = *merchant_pub;
|
dr.merchant = *merchant_pub;
|
||||||
dr.coin_pub = *coin_pub;
|
dr.coin_pub = *coin_pub;
|
||||||
|
|
||||||
|
char *contract_str = GNUNET_STRINGS_data_to_string_alloc (h_contract,
|
||||||
|
sizeof (struct GNUNET_HashCode));
|
||||||
|
char *wire_str = GNUNET_STRINGS_data_to_string_alloc (h_wire,
|
||||||
|
sizeof (struct GNUNET_HashCode));
|
||||||
|
char *merchant_pub_str = GNUNET_STRINGS_data_to_string_alloc (merchant_pub,
|
||||||
|
sizeof (struct TALER_MerchantPublicKeyP));
|
||||||
|
char *coin_pub_str = GNUNET_STRINGS_data_to_string_alloc (coin_pub,
|
||||||
|
sizeof (struct TALER_CoinSpendPublicKeyP));
|
||||||
|
printf ("verifying:\ncontract [%s]\nwire [%s]\n"
|
||||||
|
"timestamp [%llu]\nrefund deadline [%llu]\n"
|
||||||
|
"transaction id [%llu]\namount [%s %llu.%lu]\n"
|
||||||
|
"fee deposit [%s %llu.%lu]\nmerch pub [%s]\n"
|
||||||
|
"coin pub [%s]\n",
|
||||||
|
contract_str,
|
||||||
|
wire_str,
|
||||||
|
timestamp.abs_value_us,
|
||||||
|
refund_deadline.abs_value_us,
|
||||||
|
transaction_id,
|
||||||
|
amount->currency,
|
||||||
|
amount->value,
|
||||||
|
amount->fraction,
|
||||||
|
dki->fee_deposit.currency,
|
||||||
|
dki->fee_deposit.value,
|
||||||
|
dki->fee_deposit.fraction,
|
||||||
|
merchant_pub_str,
|
||||||
|
coin_pub_str);
|
||||||
|
|
||||||
|
GNUNET_free (contract_str);
|
||||||
|
GNUNET_free (wire_str);
|
||||||
|
GNUNET_free (merchant_pub_str);
|
||||||
|
GNUNET_free (coin_pub_str);
|
||||||
|
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_DEPOSIT,
|
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_DEPOSIT,
|
||||||
&dr.purpose,
|
&dr.purpose,
|
||||||
|
@ -213,49 +213,6 @@ parse_json (json_t *root,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MAJ_CMD_EDDSA_SIGNATURE:
|
|
||||||
{
|
|
||||||
struct TALER_CoinSpendSignatureP sig;
|
|
||||||
struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
|
|
||||||
size_t size;
|
|
||||||
struct MAJ_Specification sig_spec[] = {
|
|
||||||
MAJ_spec_fixed_auto ("eddsa_sig", &sig),
|
|
||||||
MAJ_spec_varsize ("eddsa_val", (void**) &purpose, &size),
|
|
||||||
MAJ_spec_end
|
|
||||||
};
|
|
||||||
|
|
||||||
if (GNUNET_OK !=
|
|
||||||
MAJ_parse_json (pos,
|
|
||||||
sig_spec))
|
|
||||||
{
|
|
||||||
GNUNET_break_op (0);
|
|
||||||
MAJ_parse_free (sig_spec);
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
if (size != ntohl (purpose->size))
|
|
||||||
{
|
|
||||||
GNUNET_break_op (0);
|
|
||||||
MAJ_parse_free (sig_spec);
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GNUNET_OK !=
|
|
||||||
GNUNET_CRYPTO_eddsa_verify (ntohl (purpose->purpose),
|
|
||||||
purpose,
|
|
||||||
&sig.eddsa_signature,
|
|
||||||
spec[i].details.eddsa_signature.pub_key))
|
|
||||||
{
|
|
||||||
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
|
||||||
"Failed to verify signature of purpose %u\n",
|
|
||||||
ntohl (purpose->purpose));
|
|
||||||
GNUNET_break_op (0);
|
|
||||||
MAJ_parse_free (sig_spec);
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
*spec[i].details.eddsa_signature.purpose_p = purpose;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MAJ_CMD_UINT16:
|
case MAJ_CMD_UINT16:
|
||||||
{
|
{
|
||||||
json_int_t val;
|
json_int_t val;
|
||||||
@ -337,10 +294,6 @@ parse_free (struct MAJ_Specification *spec,
|
|||||||
GNUNET_CRYPTO_rsa_signature_free (*spec[i].details.rsa_signature);
|
GNUNET_CRYPTO_rsa_signature_free (*spec[i].details.rsa_signature);
|
||||||
*spec[i].details.rsa_signature = NULL;
|
*spec[i].details.rsa_signature = NULL;
|
||||||
break;
|
break;
|
||||||
case MAJ_CMD_EDDSA_SIGNATURE:
|
|
||||||
GNUNET_free (*spec[i].details.eddsa_signature.purpose_p);
|
|
||||||
*spec[i].details.eddsa_signature.purpose_p = NULL;
|
|
||||||
break;
|
|
||||||
case MAJ_CMD_JSON_OBJECT:
|
case MAJ_CMD_JSON_OBJECT:
|
||||||
json_decref (*spec[i].details.obj);
|
json_decref (*spec[i].details.obj);
|
||||||
*spec[i].details.obj = NULL;
|
*spec[i].details.obj = NULL;
|
||||||
@ -535,28 +488,4 @@ MAJ_spec_rsa_signature (const char *name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Specification for parsing an EdDSA object signature with purpose.
|
|
||||||
* Also validates the signature (!).
|
|
||||||
*
|
|
||||||
* @param name name of the JSON field
|
|
||||||
* @param purpose_p where to store the purpose
|
|
||||||
* @param pub_key public key to use for validation
|
|
||||||
*/
|
|
||||||
struct MAJ_Specification
|
|
||||||
MAJ_spec_eddsa_signed_purpose (const char *name,
|
|
||||||
struct GNUNET_CRYPTO_EccSignaturePurpose **purpose_p,
|
|
||||||
const struct GNUNET_CRYPTO_EddsaPublicKey *pub_key)
|
|
||||||
{
|
|
||||||
struct MAJ_Specification ret =
|
|
||||||
{
|
|
||||||
.cmd = MAJ_CMD_EDDSA_SIGNATURE,
|
|
||||||
.field = name,
|
|
||||||
.details.eddsa_signature.purpose_p = purpose_p,
|
|
||||||
.details.eddsa_signature.pub_key = pub_key
|
|
||||||
};
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* end of mint_api_json.c */
|
/* end of mint_api_json.c */
|
||||||
|
@ -68,11 +68,6 @@ enum MAJ_Command
|
|||||||
*/
|
*/
|
||||||
MAJ_CMD_RSA_SIGNATURE,
|
MAJ_CMD_RSA_SIGNATURE,
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse object with EdDSA signature and purpose at current position.
|
|
||||||
*/
|
|
||||||
MAJ_CMD_EDDSA_SIGNATURE,
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse `const char *` JSON string at current position.
|
* Parse `const char *` JSON string at current position.
|
||||||
*/
|
*/
|
||||||
@ -309,20 +304,6 @@ MAJ_spec_amount (const char *name,
|
|||||||
struct TALER_Amount *amount);
|
struct TALER_Amount *amount);
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Specification for parsing an EdDSA object signature with purpose.
|
|
||||||
* Also validates the signature (!).
|
|
||||||
*
|
|
||||||
* @param name name of the JSON field
|
|
||||||
* @param purpose_p where to store the purpose
|
|
||||||
* @param pub_key public key to use for validation
|
|
||||||
*/
|
|
||||||
struct MAJ_Specification
|
|
||||||
MAJ_spec_eddsa_signed_purpose (const char *name,
|
|
||||||
struct GNUNET_CRYPTO_EccSignaturePurpose **purpose_p,
|
|
||||||
const struct GNUNET_CRYPTO_EddsaPublicKey *pub_key);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specification for parsing an RSA public key.
|
* Specification for parsing an RSA public key.
|
||||||
*
|
*
|
||||||
|
@ -676,6 +676,7 @@ serialize_melt_data (const struct MeltData *md,
|
|||||||
unsigned int j;
|
unsigned int j;
|
||||||
|
|
||||||
size = 0;
|
size = 0;
|
||||||
|
asize = (size_t) -1; /* make the compiler happy */
|
||||||
buf = NULL;
|
buf = NULL;
|
||||||
/* we do 2 iterations, #1 to determine total size, #2 to
|
/* we do 2 iterations, #1 to determine total size, #2 to
|
||||||
actually construct the buffer */
|
actually construct the buffer */
|
||||||
|
@ -167,13 +167,14 @@ parse_reserve_history (json_t *history,
|
|||||||
else if (0 == strcasecmp (type,
|
else if (0 == strcasecmp (type,
|
||||||
"WITHDRAW"))
|
"WITHDRAW"))
|
||||||
{
|
{
|
||||||
struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
|
struct TALER_ReserveSignatureP sig;
|
||||||
const struct TALER_WithdrawRequestPS *withdraw_purpose;
|
struct TALER_WithdrawRequestPS withdraw_purpose;
|
||||||
struct TALER_Amount amount_from_purpose;
|
struct TALER_Amount amount_from_purpose;
|
||||||
struct MAJ_Specification withdraw_spec[] = {
|
struct MAJ_Specification withdraw_spec[] = {
|
||||||
MAJ_spec_eddsa_signed_purpose ("signature",
|
MAJ_spec_fixed_auto ("signature",
|
||||||
&purpose,
|
&sig),
|
||||||
&reserve_pub->eddsa_pub),
|
MAJ_spec_fixed_auto ("details",
|
||||||
|
&withdraw_purpose),
|
||||||
MAJ_spec_end
|
MAJ_spec_end
|
||||||
};
|
};
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
@ -186,17 +187,19 @@ parse_reserve_history (json_t *history,
|
|||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
/* Check that the signature actually signed a withdraw request */
|
/* Check that the signature is a valid withdraw request */
|
||||||
if ( (ntohl (purpose->purpose) != TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW) ||
|
if (GNUNET_OK !=
|
||||||
(ntohl (purpose->size) != sizeof (struct TALER_WithdrawRequestPS)) )
|
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW,
|
||||||
|
&withdraw_purpose.purpose,
|
||||||
|
&sig.eddsa_signature,
|
||||||
|
&reserve_pub->eddsa_pub))
|
||||||
{
|
{
|
||||||
GNUNET_break_op (0);
|
GNUNET_break_op (0);
|
||||||
MAJ_parse_free (withdraw_spec);
|
MAJ_parse_free (withdraw_spec);
|
||||||
return GNUNET_SYSERR;
|
return GNUNET_SYSERR;
|
||||||
}
|
}
|
||||||
withdraw_purpose = (const struct TALER_WithdrawRequestPS *) purpose;
|
|
||||||
TALER_amount_ntoh (&amount_from_purpose,
|
TALER_amount_ntoh (&amount_from_purpose,
|
||||||
&withdraw_purpose->amount_with_fee);
|
&withdraw_purpose.amount_with_fee);
|
||||||
if (0 != TALER_amount_cmp (&amount,
|
if (0 != TALER_amount_cmp (&amount,
|
||||||
&amount_from_purpose))
|
&amount_from_purpose))
|
||||||
{
|
{
|
||||||
@ -211,8 +214,8 @@ parse_reserve_history (json_t *history,
|
|||||||
"uuid" array to remember the hashes of all
|
"uuid" array to remember the hashes of all
|
||||||
purposes, and compare the hashes to find
|
purposes, and compare the hashes to find
|
||||||
duplicates. */
|
duplicates. */
|
||||||
GNUNET_CRYPTO_hash (withdraw_purpose,
|
GNUNET_CRYPTO_hash (&withdraw_purpose,
|
||||||
ntohl (withdraw_purpose->purpose.size),
|
ntohl (withdraw_purpose.purpose.size),
|
||||||
&uuid[uuid_off]);
|
&uuid[uuid_off]);
|
||||||
for (i=0;i<uuid_off;i++)
|
for (i=0;i<uuid_off;i++)
|
||||||
{
|
{
|
||||||
|
@ -19,6 +19,7 @@ taler_mint_httpd_SOURCES = \
|
|||||||
taler-mint-httpd_admin.c taler-mint-httpd_admin.h \
|
taler-mint-httpd_admin.c taler-mint-httpd_admin.h \
|
||||||
taler-mint-httpd_deposit.c taler-mint-httpd_deposit.h \
|
taler-mint-httpd_deposit.c taler-mint-httpd_deposit.h \
|
||||||
taler-mint-httpd_reserve.c taler-mint-httpd_reserve.h \
|
taler-mint-httpd_reserve.c taler-mint-httpd_reserve.h \
|
||||||
|
taler-mint-httpd_tracking.c taler-mint-httpd_tracking.h \
|
||||||
taler-mint-httpd_wire.c taler-mint-httpd_wire.h \
|
taler-mint-httpd_wire.c taler-mint-httpd_wire.h \
|
||||||
taler-mint-httpd_refresh.c taler-mint-httpd_refresh.h
|
taler-mint-httpd_refresh.c taler-mint-httpd_refresh.h
|
||||||
taler_mint_httpd_LDADD = \
|
taler_mint_httpd_LDADD = \
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include "taler-mint-httpd_reserve.h"
|
#include "taler-mint-httpd_reserve.h"
|
||||||
#include "taler-mint-httpd_wire.h"
|
#include "taler-mint-httpd_wire.h"
|
||||||
#include "taler-mint-httpd_refresh.h"
|
#include "taler-mint-httpd_refresh.h"
|
||||||
|
#include "taler-mint-httpd_tracking.h"
|
||||||
#include "taler-mint-httpd_keystate.h"
|
#include "taler-mint-httpd_keystate.h"
|
||||||
#if HAVE_DEVELOPER
|
#if HAVE_DEVELOPER
|
||||||
#include "taler-mint-httpd_test.h"
|
#include "taler-mint-httpd_test.h"
|
||||||
@ -256,6 +257,19 @@ handle_mhd_request (void *cls,
|
|||||||
"Only POST is allowed", 0,
|
"Only POST is allowed", 0,
|
||||||
&TMH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED },
|
&TMH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED },
|
||||||
|
|
||||||
|
{ "/wire/deposits", MHD_HTTP_METHOD_GET, "application/json",
|
||||||
|
NULL, 0,
|
||||||
|
&TMH_TRACKING_handler_wire_deposits, MHD_HTTP_OK },
|
||||||
|
{ "/wire/deposits", NULL, "text/plain",
|
||||||
|
"Only GET is allowed", 0,
|
||||||
|
&TMH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED },
|
||||||
|
{ "/deposit/wtid", MHD_HTTP_METHOD_POST, "application/json",
|
||||||
|
NULL, 0,
|
||||||
|
&TMH_TRACKING_handler_deposit_wtid, MHD_HTTP_OK },
|
||||||
|
{ "/deposit/wtid", NULL, "text/plain",
|
||||||
|
"Only POST is allowed", 0,
|
||||||
|
&TMH_MHD_handler_send_json_pack_error, MHD_HTTP_METHOD_NOT_ALLOWED },
|
||||||
|
|
||||||
#if HAVE_DEVELOPER
|
#if HAVE_DEVELOPER
|
||||||
/* Client crypto-interoperability test functions */
|
/* Client crypto-interoperability test functions */
|
||||||
{ "/test", MHD_HTTP_METHOD_POST, "application/json",
|
{ "/test", MHD_HTTP_METHOD_POST, "application/json",
|
||||||
|
@ -404,10 +404,11 @@ TMH_RESPONSE_reply_deposit_success (struct MHD_Connection *connection,
|
|||||||
static json_t *
|
static json_t *
|
||||||
compile_transaction_history (const struct TALER_MINTDB_TransactionList *tl)
|
compile_transaction_history (const struct TALER_MINTDB_TransactionList *tl)
|
||||||
{
|
{
|
||||||
json_t *transaction;
|
json_t *details;
|
||||||
const char *type;
|
const char *type;
|
||||||
struct TALER_Amount value;
|
struct TALER_Amount value;
|
||||||
json_t *history;
|
json_t *history;
|
||||||
|
const struct TALER_CoinSpendSignatureP *sig;
|
||||||
const struct TALER_MINTDB_TransactionList *pos;
|
const struct TALER_MINTDB_TransactionList *pos;
|
||||||
|
|
||||||
history = json_array ();
|
history = json_array ();
|
||||||
@ -420,7 +421,7 @@ compile_transaction_history (const struct TALER_MINTDB_TransactionList *tl)
|
|||||||
struct TALER_DepositRequestPS dr;
|
struct TALER_DepositRequestPS dr;
|
||||||
const struct TALER_MINTDB_Deposit *deposit = pos->details.deposit;
|
const struct TALER_MINTDB_Deposit *deposit = pos->details.deposit;
|
||||||
|
|
||||||
type = "deposit";
|
type = "DEPOSIT";
|
||||||
value = deposit->amount_with_fee;
|
value = deposit->amount_with_fee;
|
||||||
dr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT);
|
dr.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT);
|
||||||
dr.purpose.size = htonl (sizeof (struct TALER_DepositRequestPS));
|
dr.purpose.size = htonl (sizeof (struct TALER_DepositRequestPS));
|
||||||
@ -435,12 +436,12 @@ compile_transaction_history (const struct TALER_MINTDB_TransactionList *tl)
|
|||||||
&deposit->deposit_fee);
|
&deposit->deposit_fee);
|
||||||
dr.merchant = deposit->merchant_pub;
|
dr.merchant = deposit->merchant_pub;
|
||||||
dr.coin_pub = deposit->coin.coin_pub;
|
dr.coin_pub = deposit->coin.coin_pub;
|
||||||
|
sig = &deposit->csig;
|
||||||
/* internal sanity check before we hand out a bogus sig... */
|
/* internal sanity check before we hand out a bogus sig... */
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_DEPOSIT,
|
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_DEPOSIT,
|
||||||
&dr.purpose,
|
&dr.purpose,
|
||||||
&deposit->csig.eddsa_signature,
|
&sig->eddsa_signature,
|
||||||
&deposit->coin.coin_pub.eddsa_pub))
|
&deposit->coin.coin_pub.eddsa_pub))
|
||||||
{
|
{
|
||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
@ -448,8 +449,8 @@ compile_transaction_history (const struct TALER_MINTDB_TransactionList *tl)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
transaction = TALER_json_from_eddsa_sig (&dr.purpose,
|
details = TALER_json_from_data (&dr.purpose,
|
||||||
&deposit->csig.eddsa_signature);
|
sizeof (struct TALER_DepositRequestPS));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TALER_MINTDB_TT_REFRESH_MELT:
|
case TALER_MINTDB_TT_REFRESH_MELT:
|
||||||
@ -457,7 +458,7 @@ compile_transaction_history (const struct TALER_MINTDB_TransactionList *tl)
|
|||||||
struct TALER_RefreshMeltCoinAffirmationPS ms;
|
struct TALER_RefreshMeltCoinAffirmationPS ms;
|
||||||
const struct TALER_MINTDB_RefreshMelt *melt = pos->details.melt;
|
const struct TALER_MINTDB_RefreshMelt *melt = pos->details.melt;
|
||||||
|
|
||||||
type = "melt";
|
type = "MELT";
|
||||||
value = melt->amount_with_fee;
|
value = melt->amount_with_fee;
|
||||||
ms.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_MELT);
|
ms.purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_MELT);
|
||||||
ms.purpose.size = htonl (sizeof (struct TALER_RefreshMeltCoinAffirmationPS));
|
ms.purpose.size = htonl (sizeof (struct TALER_RefreshMeltCoinAffirmationPS));
|
||||||
@ -467,12 +468,12 @@ compile_transaction_history (const struct TALER_MINTDB_TransactionList *tl)
|
|||||||
TALER_amount_hton (&ms.melt_fee,
|
TALER_amount_hton (&ms.melt_fee,
|
||||||
&melt->melt_fee);
|
&melt->melt_fee);
|
||||||
ms.coin_pub = melt->coin.coin_pub;
|
ms.coin_pub = melt->coin.coin_pub;
|
||||||
|
sig = &melt->coin_sig;
|
||||||
/* internal sanity check before we hand out a bogus sig... */
|
/* internal sanity check before we hand out a bogus sig... */
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_MELT,
|
GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_MELT,
|
||||||
&ms.purpose,
|
&ms.purpose,
|
||||||
&melt->coin_sig.eddsa_signature,
|
&sig->eddsa_signature,
|
||||||
&melt->coin.coin_pub.eddsa_pub))
|
&melt->coin.coin_pub.eddsa_pub))
|
||||||
{
|
{
|
||||||
GNUNET_break (0);
|
GNUNET_break (0);
|
||||||
@ -480,18 +481,20 @@ compile_transaction_history (const struct TALER_MINTDB_TransactionList *tl)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
transaction = TALER_json_from_eddsa_sig (&ms.purpose,
|
details = TALER_json_from_data (&ms.purpose,
|
||||||
&melt->coin_sig.eddsa_signature);
|
sizeof (struct TALER_RefreshMeltCoinAffirmationPS));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
GNUNET_assert (0);
|
GNUNET_assert (0);
|
||||||
}
|
}
|
||||||
json_array_append_new (history,
|
json_array_append_new (history,
|
||||||
json_pack ("{s:s, s:o, s:o}",
|
json_pack ("{s:s, s:o, s:o, s:o}",
|
||||||
"type", type,
|
"type", type,
|
||||||
"amount", TALER_json_from_amount (&value),
|
"amount", TALER_json_from_amount (&value),
|
||||||
"signature", transaction));
|
"signature", TALER_json_from_data (sig,
|
||||||
|
sizeof (struct TALER_CoinSpendSignatureP)),
|
||||||
|
"details", details));
|
||||||
}
|
}
|
||||||
return history;
|
return history;
|
||||||
}
|
}
|
||||||
@ -539,7 +542,6 @@ compile_reserve_history (const struct TALER_MINTDB_ReserveHistory *rh,
|
|||||||
struct TALER_Amount withdraw_total;
|
struct TALER_Amount withdraw_total;
|
||||||
struct TALER_Amount value;
|
struct TALER_Amount value;
|
||||||
json_t *json_history;
|
json_t *json_history;
|
||||||
json_t *transaction;
|
|
||||||
int ret;
|
int ret;
|
||||||
const struct TALER_MINTDB_ReserveHistory *pos;
|
const struct TALER_MINTDB_ReserveHistory *pos;
|
||||||
struct TALER_WithdrawRequestPS wr;
|
struct TALER_WithdrawRequestPS wr;
|
||||||
@ -609,14 +611,13 @@ compile_reserve_history (const struct TALER_MINTDB_ReserveHistory *rh,
|
|||||||
GNUNET_CRYPTO_rsa_public_key_hash (pos->details.withdraw->denom_pub.rsa_public_key,
|
GNUNET_CRYPTO_rsa_public_key_hash (pos->details.withdraw->denom_pub.rsa_public_key,
|
||||||
&wr.h_denomination_pub);
|
&wr.h_denomination_pub);
|
||||||
wr.h_coin_envelope = pos->details.withdraw->h_coin_envelope;
|
wr.h_coin_envelope = pos->details.withdraw->h_coin_envelope;
|
||||||
|
|
||||||
transaction = TALER_json_from_eddsa_sig (&wr.purpose,
|
|
||||||
&pos->details.withdraw->reserve_sig.eddsa_signature);
|
|
||||||
|
|
||||||
json_array_append_new (json_history,
|
json_array_append_new (json_history,
|
||||||
json_pack ("{s:s, s:o, s:o}",
|
json_pack ("{s:s, s:o, s:o, s:o}",
|
||||||
"type", "WITHDRAW",
|
"type", "WITHDRAW",
|
||||||
"signature", transaction,
|
"signature", TALER_json_from_data (&pos->details.withdraw->reserve_sig,
|
||||||
|
sizeof (struct TALER_ReserveSignatureP)),
|
||||||
|
"details", TALER_json_from_data (&wr,
|
||||||
|
sizeof (wr)),
|
||||||
"amount", TALER_json_from_amount (&value)));
|
"amount", TALER_json_from_amount (&value)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
75
src/mint/taler-mint-httpd_tracking.c
Normal file
75
src/mint/taler-mint-httpd_tracking.c
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
This file is part of TALER
|
||||||
|
Copyright (C) 2014, 2015 GNUnet e.V.
|
||||||
|
|
||||||
|
TALER is free software; you can redistribute it and/or modify it under the
|
||||||
|
terms of the GNU Affero General Public License as published by the Free Software
|
||||||
|
Foundation; either version 3, or (at your option) any later version.
|
||||||
|
|
||||||
|
TALER 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 Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License along with
|
||||||
|
TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @file taler-mint-httpd_tracking.c
|
||||||
|
* @brief Handle wire transfer tracking-related requests
|
||||||
|
* @author Christian Grothoff
|
||||||
|
*/
|
||||||
|
#include "platform.h"
|
||||||
|
#include <gnunet/gnunet_util_lib.h>
|
||||||
|
#include <jansson.h>
|
||||||
|
#include <microhttpd.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include "taler-mint-httpd_parsing.h"
|
||||||
|
#include "taler-mint-httpd_tracking.h"
|
||||||
|
#include "taler-mint-httpd_responses.h"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle a "/wire/deposits" request.
|
||||||
|
*
|
||||||
|
* @param rh context of the handler
|
||||||
|
* @param connection the MHD connection to handle
|
||||||
|
* @param[in,out] connection_cls the connection's closure (can be updated)
|
||||||
|
* @param upload_data upload data
|
||||||
|
* @param[in,out] upload_data_size number of bytes (left) in @a upload_data
|
||||||
|
* @return MHD result code
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
TMH_TRACKING_handler_wire_deposits (struct TMH_RequestHandler *rh,
|
||||||
|
struct MHD_Connection *connection,
|
||||||
|
void **connection_cls,
|
||||||
|
const char *upload_data,
|
||||||
|
size_t *upload_data_size)
|
||||||
|
{
|
||||||
|
GNUNET_break (0); // not implemented
|
||||||
|
return MHD_NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle a "/deposit/wtid" request.
|
||||||
|
*
|
||||||
|
* @param rh context of the handler
|
||||||
|
* @param connection the MHD connection to handle
|
||||||
|
* @param[in,out] connection_cls the connection's closure (can be updated)
|
||||||
|
* @param upload_data upload data
|
||||||
|
* @param[in,out] upload_data_size number of bytes (left) in @a upload_data
|
||||||
|
* @return MHD result code
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
TMH_TRACKING_handler_deposit_wtid (struct TMH_RequestHandler *rh,
|
||||||
|
struct MHD_Connection *connection,
|
||||||
|
void **connection_cls,
|
||||||
|
const char *upload_data,
|
||||||
|
size_t *upload_data_size)
|
||||||
|
{
|
||||||
|
GNUNET_break (0); // not implemented
|
||||||
|
return MHD_NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* end of taler-mint-httpd_tracking.c */
|
65
src/mint/taler-mint-httpd_tracking.h
Normal file
65
src/mint/taler-mint-httpd_tracking.h
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
This file is part of TALER
|
||||||
|
Copyright (C) 2014, 2015 GNUnet e.V.
|
||||||
|
|
||||||
|
TALER is free software; you can redistribute it and/or modify it under the
|
||||||
|
terms of the GNU Affero General Public License as published by the Free Software
|
||||||
|
Foundation; either version 3, or (at your option) any later version.
|
||||||
|
|
||||||
|
TALER 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 Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License along with
|
||||||
|
TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @file taler-mint-httpd_tracking.h
|
||||||
|
* @brief Handle wire transfer tracking-related requests
|
||||||
|
* @author Christian Grothoff
|
||||||
|
*/
|
||||||
|
#ifndef TALER_MINT_HTTPD_TRACKING_H
|
||||||
|
#define TALER_MINT_HTTPD_TRACKING_H
|
||||||
|
|
||||||
|
#include <gnunet/gnunet_util_lib.h>
|
||||||
|
#include <microhttpd.h>
|
||||||
|
#include "taler-mint-httpd.h"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle a "/wire/deposits" request.
|
||||||
|
*
|
||||||
|
* @param rh context of the handler
|
||||||
|
* @param connection the MHD connection to handle
|
||||||
|
* @param[in,out] connection_cls the connection's closure (can be updated)
|
||||||
|
* @param upload_data upload data
|
||||||
|
* @param[in,out] upload_data_size number of bytes (left) in @a upload_data
|
||||||
|
* @return MHD result code
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
TMH_TRACKING_handler_wire_deposits (struct TMH_RequestHandler *rh,
|
||||||
|
struct MHD_Connection *connection,
|
||||||
|
void **connection_cls,
|
||||||
|
const char *upload_data,
|
||||||
|
size_t *upload_data_size);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle a "/deposit/wtid" request.
|
||||||
|
*
|
||||||
|
* @param rh context of the handler
|
||||||
|
* @param connection the MHD connection to handle
|
||||||
|
* @param[in,out] connection_cls the connection's closure (can be updated)
|
||||||
|
* @param upload_data upload data
|
||||||
|
* @param[in,out] upload_data_size number of bytes (left) in @a upload_data
|
||||||
|
* @return MHD result code
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
TMH_TRACKING_handler_deposit_wtid (struct TMH_RequestHandler *rh,
|
||||||
|
struct MHD_Connection *connection,
|
||||||
|
void **connection_cls,
|
||||||
|
const char *upload_data,
|
||||||
|
size_t *upload_data_size);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
@ -103,40 +103,6 @@ TALER_json_from_abs (struct GNUNET_TIME_Absolute stamp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert a signature (with purpose) to a JSON object representation.
|
|
||||||
*
|
|
||||||
* @param purpose purpose of the signature
|
|
||||||
* @param signature the signature
|
|
||||||
* @return the JSON reporesentation of the signature with purpose
|
|
||||||
*/
|
|
||||||
json_t *
|
|
||||||
TALER_json_from_eddsa_sig (const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose,
|
|
||||||
const struct GNUNET_CRYPTO_EddsaSignature *signature)
|
|
||||||
{
|
|
||||||
json_t *root;
|
|
||||||
json_t *el;
|
|
||||||
|
|
||||||
root = json_object ();
|
|
||||||
|
|
||||||
el = json_integer ((json_int_t) ntohl (purpose->size));
|
|
||||||
json_object_set_new (root, "size", el);
|
|
||||||
|
|
||||||
el = json_integer ((json_int_t) ntohl (purpose->purpose));
|
|
||||||
json_object_set_new (root, "purpose", el);
|
|
||||||
|
|
||||||
el = TALER_json_from_data (purpose,
|
|
||||||
ntohl (purpose->size));
|
|
||||||
json_object_set_new (root, "eddsa_val", el);
|
|
||||||
|
|
||||||
el = TALER_json_from_data (signature,
|
|
||||||
sizeof (struct GNUNET_CRYPTO_EddsaSignature));
|
|
||||||
json_object_set_new (root, "eddsa_sig", el);
|
|
||||||
|
|
||||||
return root;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert RSA public key to JSON.
|
* Convert RSA public key to JSON.
|
||||||
*
|
*
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
This directory is the root of the mint's website, mainly
|
|
||||||
intended to provide a way to the user to wire funds to the
|
|
||||||
mints in the act of creating a reserve.
|
|
@ -1,79 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Fake Wire Transfer</title>
|
|
||||||
<script>
|
|
||||||
/*
|
|
||||||
@licstart The following is the entire license notice for the
|
|
||||||
JavaScript code in this page.
|
|
||||||
|
|
||||||
Copyright (C) 2014,2015 GNUnet e.V.
|
|
||||||
|
|
||||||
The JavaScript code in this page is free software: you can
|
|
||||||
redistribute it and/or modify it under the terms of the GNU
|
|
||||||
Lesser General Public License (GNU LGPL) as published by the Free Software
|
|
||||||
Foundation, either version 2.1 of the License, or (at your option)
|
|
||||||
any later version. The code is distributed WITHOUT ANY WARRANTY;
|
|
||||||
without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
||||||
FOR A PARTICULAR PURPOSE. See the GNU LGPL for more details.
|
|
||||||
|
|
||||||
As additional permission under GNU LGPL version 2.1 section 7, you
|
|
||||||
may distribute non-source (e.g., minimized or compacted) forms of
|
|
||||||
that code without the copy of the GNU LGPL normally required by
|
|
||||||
section 4, provided you include this license notice and a URL
|
|
||||||
through which recipients can access the Corresponding Source.
|
|
||||||
|
|
||||||
@licend The above is the entire license notice
|
|
||||||
for the JavaScript code in this page.
|
|
||||||
*/
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<!--
|
|
||||||
This page's main aim is to forward the fake wire transfer
|
|
||||||
request to the demonstrator and to inform the customer
|
|
||||||
about the result. In a real-world deployment, this
|
|
||||||
page would not be required as the customer would do a
|
|
||||||
wire transfer with his bank instead.
|
|
||||||
-->
|
|
||||||
<?php
|
|
||||||
|
|
||||||
// Evaluate form
|
|
||||||
$reserve_pk = $_POST['reserve_pk'];
|
|
||||||
$kudos_amount = $_POST['kudos_amount'];
|
|
||||||
$mint = $_SERVER['SERVER_NAME'];
|
|
||||||
|
|
||||||
// pack the JSON
|
|
||||||
$json = json_encode (array ('reserve_pub' => $reserve_pk,
|
|
||||||
'execution_date' => "/Date(" . time() . ")/",
|
|
||||||
'wire' => array ('type' => 'test'),
|
|
||||||
'amount' => array ('value' => intval($kudos_amount),
|
|
||||||
'fraction' => 0,
|
|
||||||
'currency' => 'KUDOS'))); // TODO 'KUDOS' example needs 'KUDOS' denom keys ..
|
|
||||||
|
|
||||||
// craft the HTTP request
|
|
||||||
$req = new http\Client\Request ("POST",
|
|
||||||
"http://" . $mint . "/admin/add/incoming",
|
|
||||||
array ("Content-Type" => "application/json"));
|
|
||||||
$req->getBody()->append ($json);
|
|
||||||
|
|
||||||
// execute HTTP request
|
|
||||||
$client = new http\Client;
|
|
||||||
$client->enqueue($req)->send ();
|
|
||||||
$resp = $client->getResponse ();
|
|
||||||
|
|
||||||
// evaluate response
|
|
||||||
$status_code = $resp->getResponseCode ();
|
|
||||||
http_response_code ($status_code);
|
|
||||||
|
|
||||||
if ($status_code != 200)
|
|
||||||
{
|
|
||||||
echo "Error $status_code when faking the wire transfer. Please report to taler@gnu.org";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
echo "Pretend wire transfer successful. Exit through the <a href=\"http://toy.taler.net\">gift shop</a> and enjoy shopping!";
|
|
||||||
}
|
|
||||||
?>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,114 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<title>Taler's "Toy" Shop</title>
|
|
||||||
<link rel="stylesheet" type="text/css" href="style.css">
|
|
||||||
<script>
|
|
||||||
/*
|
|
||||||
@licstart The following is the entire license notice for the
|
|
||||||
JavaScript code in this page.
|
|
||||||
|
|
||||||
Copyright (C) 2015 GNUnet e.V.
|
|
||||||
|
|
||||||
The JavaScript code in this page is free software: you can
|
|
||||||
redistribute it and/or modify it under the terms of the GNU
|
|
||||||
Lesser General Public License (GNU LGPL) as published by the Free Software
|
|
||||||
Foundation, either version 2.1 of the License, or (at your option)
|
|
||||||
any later version. The code is distributed WITHOUT ANY WARRANTY;
|
|
||||||
without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
||||||
FOR A PARTICULAR PURPOSE. See the GNU LGPL for more details.
|
|
||||||
|
|
||||||
As additional permission under GNU LGPL version 2.1 section 7, you
|
|
||||||
may distribute non-source (e.g., minimized or compacted) forms of
|
|
||||||
that code without the copy of the GNU LGPL normally required by
|
|
||||||
section 4, provided you include this license notice and a URL
|
|
||||||
through which recipients can access the Corresponding Source.
|
|
||||||
|
|
||||||
@licend The above is the entire license notice
|
|
||||||
for the JavaScript code in this page.
|
|
||||||
*/
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body id="css-zen-garden" onload="signal_me()">
|
|
||||||
<div class="explanation" id="zen-explanation" role="article">
|
|
||||||
<h1>Welcome to the Taler "Demo" Mint</h1>
|
|
||||||
<p>Through this page, you can wire funds to our demonstrator mint
|
|
||||||
in order to create your reserves from where withdraw your coins.
|
|
||||||
Once the reserve is created, the withdrawing of coins will be
|
|
||||||
entirely handled by the wallet, with no intervention required
|
|
||||||
to the user.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
By clicking the button "Wire funds", your wallet will be triggered to
|
|
||||||
create a new reserve's key which needs to be pasted in the dedicated
|
|
||||||
field. Fill the desired amount to fund into the key's dialog, in order
|
|
||||||
to make the wallet check when the mint get all the funds for the reserve.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<input id="wire-funds-button" type="button" value="Wire funds" disabled=true
|
|
||||||
onclick='wire_funds();'></input>
|
|
||||||
</div>
|
|
||||||
<form id="reserve-form" name="tform" action="/fake_wire_transfer.php" method="POST">
|
|
||||||
<div class="participation" id="fake-wire">
|
|
||||||
<br>
|
|
||||||
Paste your reserve public key here (right-click, "paste"):
|
|
||||||
<input type="text" name="reserve_pk"></input>
|
|
||||||
<br>
|
|
||||||
Amount to credit to your reserve:
|
|
||||||
<select id="amount" name="kudos_amount">
|
|
||||||
<option value="1">1 KUDOS</option>
|
|
||||||
<option value="2">2 KUDOS</option>
|
|
||||||
<option value="5">5 KUDOS</option>
|
|
||||||
<option value="10">10 KUDOS</option>
|
|
||||||
<option value="1000">1000 KUDOS</option>
|
|
||||||
</select>
|
|
||||||
<br>
|
|
||||||
<input type="submit" value="Submit"></input>
|
|
||||||
<br>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<script type="text/javascript">
|
|
||||||
|
|
||||||
/* The wallet should send this signal only when:
|
|
||||||
- it gets installed
|
|
||||||
- it gets a 'taler-wire-mfirst' event */
|
|
||||||
|
|
||||||
document.body.addEventListener("taler-wallet-present",
|
|
||||||
has_taler_wallet_cb,
|
|
||||||
false);
|
|
||||||
|
|
||||||
document.body.addEventListener("taler-unload",
|
|
||||||
no_taler_wallet_cb,
|
|
||||||
false);
|
|
||||||
|
|
||||||
document.body.addEventListener("taler-load",
|
|
||||||
signal_me,
|
|
||||||
false);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function wire_funds(){
|
|
||||||
var trigger = new Event("taler-create-reserve");
|
|
||||||
document.body.dispatchEvent(trigger);
|
|
||||||
};
|
|
||||||
|
|
||||||
/* The mint signals itself to the wallet */
|
|
||||||
function signal_me(){
|
|
||||||
var eve = new Event('taler-checkout-probe');
|
|
||||||
document.body.dispatchEvent(eve);
|
|
||||||
};
|
|
||||||
|
|
||||||
function has_taler_wallet_cb(){
|
|
||||||
var button = document.getElementById("wire-funds-button");
|
|
||||||
button.removeAttribute("disabled");
|
|
||||||
}
|
|
||||||
|
|
||||||
function no_taler_wallet_cb(){
|
|
||||||
var button = document.getElementById("wire-funds-button");
|
|
||||||
button.setAttribute("disabled", "true");
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,328 +0,0 @@
|
|||||||
/* css Zen Garden submission 020 - 'Friendly Beaches' by Sophie G - www.sophie-g.net */
|
|
||||||
/* css released under Creative Commons ShareAlike License v1.0 - http://creativecommons.org/licenses/sa/1.0/ */
|
|
||||||
/* All associated graphics copyright 2003, Sophie G */
|
|
||||||
|
|
||||||
|
|
||||||
/* IMPORTANT */
|
|
||||||
/* This design is not a template. You may not reproduce it elsewhere without the designer's written permission. */
|
|
||||||
/* The CSS itself may freely be used for anything you wish, but the associated graphics belong to the designer. */
|
|
||||||
/* What you may use - .css files. What you may not use - .jpg, .gif, and .png files. */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
body {
|
|
||||||
background-color: #FFFFFF;
|
|
||||||
margin: 0px;
|
|
||||||
padding: 10px;
|
|
||||||
font-family: Ubuntu, Tahoma, Sans;
|
|
||||||
font-size: 90%;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
line-height: 180%;
|
|
||||||
}
|
|
||||||
.page-wrapper {
|
|
||||||
background-color: #EDEEF0;
|
|
||||||
border: 1px solid #DAD5D9;
|
|
||||||
padding: 0px;
|
|
||||||
margin: 0px;
|
|
||||||
}
|
|
||||||
abbr {
|
|
||||||
border-bottom: 1px #6BA0D2 dashed;
|
|
||||||
}
|
|
||||||
header,h1 {
|
|
||||||
font-family: Impact, Georgia, serif;
|
|
||||||
background-color: #FFFFFF;
|
|
||||||
}
|
|
||||||
header h1 {
|
|
||||||
height: 190px;
|
|
||||||
margin: 0px;
|
|
||||||
background-color: black;
|
|
||||||
background-image: url(Gala.jpg);
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
}
|
|
||||||
header h1, header h2 {
|
|
||||||
text-indent: 100%;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
header h2 {
|
|
||||||
background-color: #EDEEF0;
|
|
||||||
margin: 0px;
|
|
||||||
height: 24px;
|
|
||||||
padding: 0px 14px 2px 14px;
|
|
||||||
background-image: url(headerh2.gif);
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
}
|
|
||||||
header h2 abbr {
|
|
||||||
color: #FFF;
|
|
||||||
border-bottom: 1px #FFF dashed;
|
|
||||||
}
|
|
||||||
.summary p:first-child {
|
|
||||||
position: absolute;
|
|
||||||
right: 21px;
|
|
||||||
top: 21px;
|
|
||||||
width: 12em;
|
|
||||||
height: 165px;
|
|
||||||
padding: 3px 0 0 0;
|
|
||||||
margin: 0px;
|
|
||||||
border: 1px solid #0C2953;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 90%;
|
|
||||||
font-family: Impact, Georgia, serif;
|
|
||||||
line-height: 110%;
|
|
||||||
color: #FFF;
|
|
||||||
background-image: url(summary.jpg);
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: 50% 100%;
|
|
||||||
background-color: #0C2953;
|
|
||||||
}
|
|
||||||
.preamble {
|
|
||||||
padding: 0px 15em 0px 3em;
|
|
||||||
}
|
|
||||||
.preamble h3 {
|
|
||||||
margin: 15px 0px 0px 0px;
|
|
||||||
padding: 6px 20px 2px 6px;
|
|
||||||
text-align: left;
|
|
||||||
font-size: 180%;
|
|
||||||
font-variant: small-caps;
|
|
||||||
color: #6BA0D2;
|
|
||||||
background-image: url(bordDroitPreambleh3.gif);
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: 100% 0px;
|
|
||||||
background-color: #F6F7F7;
|
|
||||||
}
|
|
||||||
.preamble h3::before {
|
|
||||||
content: " ";
|
|
||||||
display: inline-block;
|
|
||||||
padding: 35px 0px 30px 48px;
|
|
||||||
background-image: url(preambleShell.jpg);
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: 0px 50%;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
.preamble p {
|
|
||||||
text-align: justify;
|
|
||||||
}
|
|
||||||
.preamble p:nth-child(2), .preamble p:nth-child(3) {
|
|
||||||
margin: 0px;
|
|
||||||
padding: 10px 20px 2px 6px;
|
|
||||||
background-image: url(bordDroitPreamble.gif);
|
|
||||||
background-repeat: repeat-y;
|
|
||||||
background-position: 100% 0px;
|
|
||||||
background-color: #F6F7F7;
|
|
||||||
}
|
|
||||||
.preamble p:nth-child(4) {
|
|
||||||
margin: 0px;
|
|
||||||
padding: 0px;
|
|
||||||
background-image: url(bordBasPreamble.gif);
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: 100% 100%;
|
|
||||||
background-color: #F6F7F7;
|
|
||||||
padding: 10px 20px 20px 6px;
|
|
||||||
}
|
|
||||||
.preamble p:nth-child(4)::after {
|
|
||||||
content: " ";
|
|
||||||
display: block;
|
|
||||||
margin: 0px;
|
|
||||||
padding: 0 20px 0 6px;
|
|
||||||
background-image: url(bordBasPreambleGauche.gif);
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: 0% 100%;
|
|
||||||
}
|
|
||||||
.supporting {
|
|
||||||
margin: 0px;
|
|
||||||
padding: 10px 16em 0px 1em;
|
|
||||||
font-size: 90%;
|
|
||||||
}
|
|
||||||
.explanation, .participation, .benefits, .requirements {
|
|
||||||
border: 2px solid #FFF;
|
|
||||||
padding: 0px;
|
|
||||||
}
|
|
||||||
.explanation {
|
|
||||||
margin: 0px 0px 10px 0px;
|
|
||||||
}
|
|
||||||
.participation {
|
|
||||||
margin: 0px 0px 10px 0px;
|
|
||||||
float: left;
|
|
||||||
width: 30%;
|
|
||||||
}
|
|
||||||
.benefits {
|
|
||||||
margin: 0px 0px 10px 32%;
|
|
||||||
}
|
|
||||||
.requirements {
|
|
||||||
margin: 0px 0px 10px 32%;
|
|
||||||
}
|
|
||||||
.supporting h3 {
|
|
||||||
margin: 0px;
|
|
||||||
padding: 5px 30px 1px 2px;
|
|
||||||
text-align: left;
|
|
||||||
font-size: 120%;
|
|
||||||
font-variant: small-caps;
|
|
||||||
color: #6BA0D2;
|
|
||||||
border-bottom: 1px solid #6BA0D2;
|
|
||||||
background-color: #F6F7F7;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: 100% 50%;
|
|
||||||
}
|
|
||||||
.explanation h3 {
|
|
||||||
background-image: url(explanationShell.jpg);
|
|
||||||
}
|
|
||||||
.supporting form {
|
|
||||||
padding: 30px;
|
|
||||||
display: inline-block;
|
|
||||||
clear: both;
|
|
||||||
width: 120em;
|
|
||||||
}
|
|
||||||
.supporting input {
|
|
||||||
margin: 8px;
|
|
||||||
}
|
|
||||||
.participation h3 {
|
|
||||||
background-image: url(participationShell.jpg);
|
|
||||||
}
|
|
||||||
.benefits h3 {
|
|
||||||
background-image: url(benefitsShell.jpg);
|
|
||||||
}
|
|
||||||
.requirements h3 {
|
|
||||||
background-image: url(requirementsRock.jpg);
|
|
||||||
}
|
|
||||||
.supporting p {
|
|
||||||
text-align: justify;
|
|
||||||
margin: 10px 0px 0px 0px;
|
|
||||||
padding: 1px 3px 2px 3px;
|
|
||||||
}
|
|
||||||
.supporting a:link {
|
|
||||||
color: #0083FF;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
.supporting a:visited {
|
|
||||||
color: #204160;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
.supporting a:hover, .supporting a:active {
|
|
||||||
color: #8C0000;
|
|
||||||
font-weight: bold;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
.sidebar, .summary p:last-child {
|
|
||||||
font-size: 90%;
|
|
||||||
font-family: Impact, Georgia, serif;
|
|
||||||
position: absolute;
|
|
||||||
right: 21px;
|
|
||||||
width: 12em;
|
|
||||||
border: 1px solid #0C2953;
|
|
||||||
padding: 0px;
|
|
||||||
margin: 0px;
|
|
||||||
background-color: #A4ACB3;
|
|
||||||
}
|
|
||||||
.summary p:last-child {
|
|
||||||
height: 50px;
|
|
||||||
text-align: center;
|
|
||||||
top: 217px;
|
|
||||||
font-size: 90%;
|
|
||||||
display: block;
|
|
||||||
padding: 3px 0;
|
|
||||||
color: #FFF;
|
|
||||||
}
|
|
||||||
.sidebar {
|
|
||||||
top: 266px;
|
|
||||||
}
|
|
||||||
.sidebar h3 {
|
|
||||||
background-color: #0C2953;
|
|
||||||
color: #FFF;
|
|
||||||
margin: 0px;
|
|
||||||
padding: 30px 1px 1px 1px;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
}
|
|
||||||
.sidebar h3.select {
|
|
||||||
background-image: url(selecth3.jpg);
|
|
||||||
background-position: 50% 0%;
|
|
||||||
}
|
|
||||||
.sidebar h3.favorites {
|
|
||||||
border-top: 1px solid #0C2953;
|
|
||||||
background-image: url(favoritesh3.jpg);
|
|
||||||
background-position: 40% 100%;
|
|
||||||
}
|
|
||||||
.sidebar h3.archives {
|
|
||||||
border-top: 1px solid #0C2953;
|
|
||||||
background-image: url(archivesh3.jpg);
|
|
||||||
background-position: 40% 100%;
|
|
||||||
}
|
|
||||||
.sidebar h3.resources {
|
|
||||||
border-top: 1px solid #0C2953;
|
|
||||||
background-image: url(resourcesh3.jpg);
|
|
||||||
background-position: 50% 30%;
|
|
||||||
}
|
|
||||||
.sidebar ul {
|
|
||||||
list-style-type: none;
|
|
||||||
font-size: 90%;
|
|
||||||
color: #FFF;
|
|
||||||
margin: 0px;
|
|
||||||
padding: 0px;
|
|
||||||
background-color: #A4ACB3;
|
|
||||||
}
|
|
||||||
.sidebar li {
|
|
||||||
padding: 3px 2px 3px 2px;
|
|
||||||
margin-bottom: 4px;
|
|
||||||
}
|
|
||||||
.sidebar li:hover {
|
|
||||||
padding: 2px 1px 2px 1px;
|
|
||||||
border: 1px dotted #0C2953;
|
|
||||||
background-color: #6BA0D2;
|
|
||||||
}
|
|
||||||
.summary p:last-child a:link {
|
|
||||||
color: #FFF;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
.summary p:last-child a:visited {
|
|
||||||
color: #204160;
|
|
||||||
}
|
|
||||||
.summary p:last-child a:hover, .summary p:last-child a:active {
|
|
||||||
color: #FFD800;
|
|
||||||
font-weight: bold;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
.sidebar a:link, .sidebar a:visited {
|
|
||||||
border-left: 6px solid #FFF;
|
|
||||||
padding-left: 2px;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #FFF;
|
|
||||||
}
|
|
||||||
.sidebar a:visited {
|
|
||||||
color: #204160;
|
|
||||||
}
|
|
||||||
.sidebar a:hover, .sidebar a:active {
|
|
||||||
border-left: 6px solid #FFD800;
|
|
||||||
padding-left: 2px;
|
|
||||||
color: #FFD800;
|
|
||||||
text-decoration: none;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
.sidebar a.designer-name:link, .sidebar a.designer-name:visited {
|
|
||||||
border-left: none;
|
|
||||||
padding-left: 0px;
|
|
||||||
font-weight: normal;
|
|
||||||
color: #FFF;
|
|
||||||
}
|
|
||||||
.sidebar a.designer-name:hover, .sidebar a.designer-name:active {
|
|
||||||
border-left: none;
|
|
||||||
padding-left: 0px;
|
|
||||||
color: #FFD800;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
.sidebar abbr {
|
|
||||||
border-bottom: 1px #FFF dashed;
|
|
||||||
}
|
|
||||||
footer {
|
|
||||||
clear: both;
|
|
||||||
text-align: right;
|
|
||||||
margin: 0px -16em 0px 0px;
|
|
||||||
padding: 25px 0px 0px 0px;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-image: url(signSoph.gif);
|
|
||||||
background-position: 0% 95%;
|
|
||||||
}
|
|
||||||
footer a {
|
|
||||||
font-size: 70%;
|
|
||||||
font-family: Impact, Georgia, serif;
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user