2013-10-10 02:44:53 +00:00
< ? php defined ( 'SYSPATH' ) or die ( 'No direct access allowed.' );
/**
* This class supports Services
*
* @ package SSL
* @ category Models
* @ author Deon George
* @ copyright ( c ) 2009 - 2013 Open Source Billing
* @ license http :// dev . osbill . net / license . html
*/
class Model_Service_Plugin_Ssl extends Model_Service_Plugin {
protected $_table_name = 'service__ssl' ;
protected $_updated_column = FALSE ;
// Relationships
protected $_belongs_to = array (
'service' => array (),
);
protected $_has_one = array (
2013-11-08 11:02:32 +00:00
'ca' => array ( 'model' => 'SSL_CA' , 'far_key' => 'ssl_ca_id' , 'foreign_key' => 'id' ),
2013-10-10 02:44:53 +00:00
);
protected $_display_filters = array (
'csr' => array (
array ( 'SSL::csrsubject' , array ( ':value' )),
),
'cert' => array (
array ( 'SSL::subject' , array ( ':value' )),
),
);
2013-11-28 06:41:34 +00:00
protected $_save_message = TRUE ;
2013-10-10 02:44:53 +00:00
// Required abstract functions
2013-11-28 06:41:34 +00:00
2013-11-08 11:02:32 +00:00
public function expire ( $format = FALSE ) {
return $this -> _so -> get_valid_to ( $format );
}
public function name () {
return ( $this -> cert AND $this -> ca -> loaded ()) ? sprintf ( '%s:%s' , $this -> ca -> subject (), $this -> display ( 'cert' )) : $this -> display ( 'csr' );
}
2013-11-28 06:41:34 +00:00
public function password () {} // Not used
public function username () {} // Not used
// Local functions
2013-11-08 11:02:32 +00:00
2013-10-10 02:44:53 +00:00
private $_so = NULL ;
/**
* Resolve any queries to certificate details
*/
public function __call ( $name , $args ) {
$m = 'get_' . $name ;
2015-09-29 01:54:45 +00:00
if ( $this -> isCSR () AND method_exists ( $this , $m ))
return $this -> { $m }( $args );
elseif ( method_exists ( $this -> _so , $m ))
2013-10-10 02:44:53 +00:00
return $this -> _so -> { $m }( $args );
2015-09-29 01:54:45 +00:00
2013-10-10 02:44:53 +00:00
else
throw new Kohana_Exception ( 'Unknown method :method' , array ( ':method' => $name ));
}
// We want to inject the SSL object into this Model
protected function _load_values ( array $values ) {
parent :: _load_values ( $values );
if ( $this -> cert )
$this -> _so = SSL :: instance ( $this -> cert );
return $this ;
}
2015-09-29 01:54:45 +00:00
/**
* Is this just a CSR ?
*/
public function isCSR () {
return ! $this -> cert AND $this -> csr ;
}
2013-10-10 02:44:53 +00:00
/**
2013-12-02 04:16:28 +00:00
* Return all our CA Certs for this certificate
2013-10-10 02:44:53 +00:00
*/
2013-12-02 04:16:28 +00:00
public function cacerts () {
$result = array ();
$x = $this -> ssl_ca_id ;
while ( $x ) {
$sco = ORM :: factory ( 'SSL_CA' , $x );
array_push ( $result , $sco -> sign_cert );
$x = $sco -> parent_ssl_ca_id ;
2013-10-10 02:44:53 +00:00
}
2013-12-02 04:16:28 +00:00
return $result ;
2013-10-10 02:44:53 +00:00
}
public function download_button () {
if ( ! $this -> service -> status OR ! preg_match ( '/client/' , $this -> service -> product -> plugin () -> extensions ) OR $this -> valid_to () < time ())
return '' ;
2013-06-04 11:50:41 +00:00
$output = Form :: open ( URL :: link ( 'user' , 'ssl/download' ), array ( 'class' => 'form-inline' ));
2013-10-10 02:44:53 +00:00
$output .= Form :: hidden ( 'sid' , $this -> service -> id );
2013-06-04 11:50:41 +00:00
$output .= '<div class="input-append">' ;
2013-07-05 06:11:37 +00:00
$output .= Form :: password ( 'passwd' , '' , array ( 'placeholder' => _ ( 'Choose a password' ), 'required' , 'nocg' => TRUE , 'pattern' => '.{6,}' , 'title' => 'Minimum 6 chars' ));
2013-06-04 11:50:41 +00:00
$output .= Form :: button ( 'download' , 'Download' , array ( 'class' => 'btn btn-default' , 'nocg' => TRUE ));
$output .= '</div>' ;
$output .= Form :: close ();
2013-10-10 02:44:53 +00:00
return $output ;
}
2015-09-29 01:54:45 +00:00
public function get_dn () {
return SSL :: csrsubject ( $this -> csr );
}
public function get_valid_to () {
// @todo
return 'Unknown' ;
}
2013-11-08 11:02:32 +00:00
/**
* Renew an SSL Certificate
*/
2015-09-29 01:54:45 +00:00
// @todo: Renew renews the expiry date as 1 day too early.
2013-11-08 11:02:32 +00:00
public function renew ( $force = FALSE ) {
2013-10-10 02:44:53 +00:00
$ssl_conf = Kohana :: $config -> load ( 'ssl' );
2015-09-29 01:54:45 +00:00
if ( $this -> cert ) {
$sslo = SSL :: instance ( $this -> cert );
// If our certificate is not old enough skip
if ( $sslo -> get_valid_to () > time () + $ssl_conf [ 'min_renew_days' ] * 86400 AND ! $force )
return FALSE ;
} elseif ( ! $this -> csr ) {
throw new Kohana_Exception ( 'Unable to renew, no CERT or CSR' );
}
2013-10-10 02:44:53 +00:00
2013-11-08 11:02:32 +00:00
$today = mktime ( 0 , 0 , 0 , date ( 'n' ), date ( 'j' ), date ( 'Y' ));
$days = ( int )(( $this -> service -> invoiced_to () - $today ) / 86400 );
$res = openssl_csr_sign ( $this -> csr , $this -> ca -> sign_cert , $this -> ca -> sign_pk , $days , array (
2013-10-10 02:44:53 +00:00
'config' => $ssl_conf [ 'config' ],
'x509_extensions' => $this -> service -> product -> plugin () -> extensions ,
'digest_alg' => 'sha1' ,
), time ());
if ( $res AND openssl_x509_export ( $res , $cert )) {
$this -> cert = $cert ;
$this -> save ();
return TRUE ;
2013-11-08 11:02:32 +00:00
2013-10-10 02:44:53 +00:00
} else {
print_r ( array (
'csr' => $this -> csr ,
2013-11-08 11:02:32 +00:00
'ca' => $this -> ca -> sign_cert ,
'capk' => $this -> ca -> sign_pk ,
2013-10-10 02:44:53 +00:00
'days' => $this -> service -> product -> plugin () -> days ,
'ssl' => $ssl_conf ,
'x509e' => $this -> service -> product -> plugin () -> extensions
));
throw new Kohana_Exception ( 'Error Creating SSL Certificate :error' , array ( ':error' => openssl_error_string ()));
}
}
2013-12-02 04:16:28 +00:00
public function validCA () {
return $this -> ca -> validParent ();
}
// If we change the SSL certificate, we need to reload our SSL object
public function values ( array $values , array $expected = NULL ) {
parent :: values ( $values , $expected );
if ( array_key_exists ( 'cert' , $values ))
$this -> _so = SSL :: instance ( $this -> cert );
return $this ;
}
/**
* Get specific service details for use in other modules
* For Example : Invoice
*
* @ todo Make the rendered items configurable
* @ todo Change this method name , now that it is public
*/
// @todo This needs to be validated for this model
public function _details ( $type ) {
switch ( $type ) {
case 'invoice_detail_items' :
return array ();
break ;
default :
return parent :: $_details ( $type );
}
}
2013-10-10 02:44:53 +00:00
}
?>