Skip to content

Commit

Permalink
Refactored aktiasppop gateway to separate gateways for aktia, sp (sää…
Browse files Browse the repository at this point in the history
…stöpankki) and pop pankki.

Security fix for incoming payments, use strcmp instead of php == for mac string comparison.
  • Loading branch information
tcmug committed Nov 11, 2014
1 parent d617c5a commit bf4245a
Show file tree
Hide file tree
Showing 16 changed files with 246 additions and 60 deletions.
39 changes: 35 additions & 4 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ Used by:
http://drupal.org/project/uc_finnish_payments
http://drupal.org/project/commerce_finnish_payments

Initial development was sponsored by Mearra.
Initial development was sponsored by Mearra (which is today part of Wunderkraut)


Supported gateways:

Aktia / Säästöpankki / Paikallisosuuspankki
Aktia
Säästöpankki
POP Pankki
Ålandsbanken
Handelsbanken
Luottokunta
Expand All @@ -37,7 +39,8 @@ Supported actions:



For testing use the accounts listed below. See test.php for usage example.
For testing use the accounts listed below. PLEASE SEE test.php for usage example.



Custom:
Expand Down Expand Up @@ -90,6 +93,8 @@ Custom:
Samlink:

No support for selectable languages or due dates (only express payments are supported).

Versions 002 and 003 are supported. Aktia uses version 010 only.

Handelsbanken

Expand All @@ -101,7 +106,22 @@ Samlink:
proper ids and passwords provided in the process


Aktia/SP/POP
Aktia

For Aktia you must use version 010.

Receiver (owner)
public: 0000000000
private: 11111111111111111111

Client:
id: 12345678
password: 123456
confirmation: 1234

Säästöpankki

For Säästöpankki you can use either versions 002 or 003.

Receiver (owner)
public: 0000000000
Expand All @@ -110,6 +130,17 @@ Samlink:
Client:
proper ids and passwords provided in the process

POP Pankki

For POP you can use either versions 002 or 003.

Receiver (owner)
public: 0000000000
private: 11111111111111111111

Client:
proper ids and passwords provided in the process.


Crosskey:

Expand Down
21 changes: 21 additions & 0 deletions gateways/aktia.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php
/**
* Gateway for Aktia
*/

require "samlink.php";

class FpiapiGatewayAktia extends FpiapiGatewaySamlink {

/**
* Constructor
*/
public function __construct() {
parent::__construct();
$this->name = "Aktia";
$this->postUrl = 'https://auth.aktia.fi/vm';
$this->queryUrl = 'https://ebank.aktia.fi/vmapi/kysely.html';
}


}
20 changes: 0 additions & 20 deletions gateways/aktiasppop.php

This file was deleted.

2 changes: 1 addition & 1 deletion gateways/crosskey.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public function isPaymentCompleted() {
$mac = implode('&', $fields) . "&" . $this->configuration['privateKey'] . "&";
$mac = strtoupper(md5($mac));

return $mac == $params['AAB-RETURN-MAC'];
return strcmp($mac, $params['AAB-RETURN-MAC']) === 0;

}

Expand Down
2 changes: 1 addition & 1 deletion gateways/danskebank.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public function isPaymentCompleted() {
$mac = $this->configuration['privateKey'] . '&' . implode('&', $fields) . '&';
$mac = strtolower(hash('sha256', $mac));

return $mac == $params['TARKISTE'];
return strcmp($mac, $params['TARKISTE']) === 0;

}

Expand Down
8 changes: 8 additions & 0 deletions gateways/gateway.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ public function getPaymentUrl() {
return $this->postUrl;
}

/**
* setPaymentUrl
* set the forms post URL
*/
public function setPaymentUrl($url) {
$this->postUrl = $url;
}

/**
* getPaymentUrl
* retreive the query url
Expand Down
2 changes: 1 addition & 1 deletion gateways/luottokunta.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public function isPaymentCompleted() {
$mac_str = implode("&", $fields);
$mac = hash('sha256', $mac_str);

return strtolower($mac) == strtolower($params['LKMAC']);
return strcmp(strtolower($mac), strtolower($params['LKMAC'])) === 0;
}

protected function getFieldArrayForResponse() {
Expand Down
2 changes: 1 addition & 1 deletion gateways/nordea.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public function isPaymentCompleted() {
$mac = implode('&', $fields) . "&" . $this->configuration['privateKey'] . "&";
$mac = strtoupper(md5($mac));

return $mac == $params['RETURN_MAC'];
return strcmp($mac, $params['RETURN_MAC']) === 0;

}

Expand Down
2 changes: 1 addition & 1 deletion gateways/osuuspankki.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public function isPaymentCompleted() {
$mac = implode('', $fields) . $this->configuration['privateKey'];
$mac = strtoupper(md5($mac));

return $mac == $params['TARKISTE'];
return strcmp($mac, $params['TARKISTE']) === 0;

}

Expand Down
2 changes: 1 addition & 1 deletion gateways/paytrail.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ public function isPaymentCompleted() {
$mac = implode('|', $fields) . '|' . $this->configuration['privateKey'];
$mac = strtoupper(md5($mac));

return $mac == $params['RETURN_AUTHCODE'];
return strcmp($mac, $params['RETURN_AUTHCODE']) === 0;
}

}
20 changes: 20 additions & 0 deletions gateways/pop.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php
/**
* Gateway for POP Pankki
*/

require "samlink.php";

class FpiapiGatewayPOP extends FpiapiGatewaySamlink {

/**
* Constructor
*/
public function __construct() {
parent::__construct();
$this->name = "POP Pankki";
$this->postUrl = 'https://verkkomaksu.poppankki.fi/vm/login.html';
$this->queryUrl = 'https://verkkomaksu.poppankki.fi/vm/vm/kysely.html';
}

}
140 changes: 112 additions & 28 deletions gateways/samlink.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,33 +20,81 @@ public function __construct() {
$this->hasQueryAbility = true;
$this->hasRefundAbility = false;
}

/**
* getPaymentFields()
* @see fpiapi/gateways/FpiapiGateway::getPaymentFields()
*/
public function getPaymentFields() {

$fields = array(
'NET_VERSION' => "002",
'NET_STAMP' => $this->transaction->getUid(),
'NET_SELLER_ID' => $this->configuration['publicKey'],
'NET_AMOUNT' => $this->transaction->getSum(),
'NET_REF' => $this->transaction->getReferenceNumber(),
'NET_DATE' => 'EXPRESS',
'NET_CUR' => $this->getCurrency(),
'NET_RETURN' => $this->getReturnUrl(),
'NET_CANCEL' => $this->getErrorUrl(),
'NET_REJECT' => $this->getErrorUrl()
);
switch ($this->configuration['version']) {
case '002':
$fields = array(
'NET_VERSION' => "002",
'NET_STAMP' => $this->transaction->getUid(),
'NET_SELLER_ID' => $this->configuration['publicKey'],
'NET_AMOUNT' => $this->transaction->getSum(),
'NET_REF' => $this->transaction->getReferenceNumber(),
'NET_DATE' => 'EXPRESS',
'NET_CUR' => $this->getCurrency(),
'NET_RETURN' => $this->getReturnUrl(),
'NET_CANCEL' => $this->getErrorUrl(),
'NET_REJECT' => $this->getErrorUrl()
);
$algorithm = 'md5';
break;

case '010': // Specific to aktia
$fields = array(
'NET_VERSION' => "010",
'NET_STAMP' => $this->transaction->getUid(),
'NET_SELLER_ID' => $this->configuration['publicKey'],
'NET_AMOUNT' => $this->transaction->getSum(),
'NET_REF' => $this->transaction->getReferenceNumber(),
'NET_DATE' => 'EXPRESS',
'NET_CUR' => $this->getCurrency(),
'NET_RETURN' => $this->getReturnUrl(),
'NET_CANCEL' => $this->getErrorUrl(),
'NET_REJECT' => $this->getErrorUrl(),
'NET_ALG' => '03',
'NET_KEYVERS' => '0001'
);
$algorithm = 'sha256';
break;

case '003': // Also the default.
default:
$fields = array(
'NET_VERSION' => "003",
'NET_STAMP' => $this->transaction->getUid(),
'NET_SELLER_ID' => $this->configuration['publicKey'],
'NET_AMOUNT' => $this->transaction->getSum(),
'NET_REF' => $this->transaction->getReferenceNumber(),
'NET_DATE' => 'EXPRESS',
'NET_CUR' => $this->getCurrency(),
'NET_RETURN' => $this->getReturnUrl(),
'NET_CANCEL' => $this->getErrorUrl(),
'NET_REJECT' => $this->getErrorUrl(),
'NET_ALG' => '03',
);
$algorithm = 'sha256';
break;
}

// Calculate mac accordingly...
$mac = implode('&', $fields) . "&" . $this->configuration['privateKey'] . "&";
$mac = strtolower(md5($mac));
$mac = strtoupper(hash($algorithm, $mac, FALSE));

$fields['NET_MAC'] = $mac;
$fields['NET_CONFIRM'] = "YES";
//$fields['NET_LANG'] = $codes[$this->getLanguage()];
if (isset($this->configuration['accountNumber'])) {
$fields['NET_SELLER_ACC'] = $this->configuration['accountNumber'];
}

if (isset($this->configuration['accountName'])) {
$fields['NET_NAME'] = $this->configuration['accountName'];
}

$fields['NET_MAC'] = $mac;
$fields['NET_CONFIRM'] = "YES";

return $fields;

Expand All @@ -61,23 +109,59 @@ public function isPaymentCompleted() {

$params = &$_REQUEST;

$fields = array(
isset($params['NET_RETURN_VERSION']) ? $params['NET_RETURN_VERSION'] : NULL,
$this->transaction->getUid(),
$this->transaction->getReferenceNumber(),
isset($params['NET_RETURN_PAID']) ? $params['NET_RETURN_PAID'] : NULL,
$this->configuration['privateKey']
);
if (!isset($params['NET_RETURN_VERSION'])) {
return FALSE;
}

switch ($params['NET_RETURN_VERSION']) {
case '002':
$fields = array(
isset($params['NET_RETURN_VERSION']) ? $params['NET_RETURN_VERSION'] : NULL,
$this->transaction->getUid(),
$this->transaction->getReferenceNumber(),
isset($params['NET_RETURN_PAID']) ? $params['NET_RETURN_PAID'] : NULL,
$this->configuration['privateKey']
);
$algorithm = 'md5';
break;

case '010': // Specific to Aktia
$fields = array(
isset($params['NET_RETURN_VERSION']) ? $params['NET_RETURN_VERSION'] : NULL,
isset($params['NET_ALG']) ? $params['NET_ALG'] : NULL,
$this->transaction->getUid(),
$this->transaction->getReferenceNumber(),
isset($params['NET_RETURN_PAID']) ? $params['NET_RETURN_PAID'] : NULL,
isset($params['NET_KEYVERS']) ? $params['NET_KEYVERS'] : NULL,
$this->configuration['privateKey']
);
$algorithm = 'sha256';
break;

case '003':
$fields = array(
isset($params['NET_RETURN_VERSION']) ? $params['NET_RETURN_VERSION'] : NULL,
$this->transaction->getUid(),
$this->transaction->getReferenceNumber(),
isset($params['NET_RETURN_PAID']) ? $params['NET_RETURN_PAID'] : NULL,
isset($params['NET_ALG']) ? $params['NET_ALG'] : NULL,
$this->configuration['privateKey']
);
$algorithm = 'sha256';
break;

default:
return FALSE;
}

if (!$this->checkFields($fields)) {
return false;
}

$mac = implode('&', $fields) . '&';
$mac = strtoupper(hash($algorithm, $mac, FALSE));

$mac = strtoupper(md5($mac));

return $mac == $params['NET_RETURN_MAC'];
return strcmp($mac, $params['NET_RETURN_MAC']) === 0;

}

Expand Down
Loading

0 comments on commit bf4245a

Please sign in to comment.