Re: [HACKERS] New functions

2015-03-22 Thread Воронин Дмитрий

  Please, attach new version of my patch to commitfest page.

Micheal, I found a way to attach patch. sorry to trouble.
-- 
Best regards, Dmitry Voronin


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


[HACKERS] Question about TEMP tables

2015-03-17 Thread Воронин Дмитрий
Hello, all.

We can create temp namespaces and temp objects that contains it. So, for 
example, temp table will be create at pg_temp_N (N - backendID). But afrer 
cluster init we have pg_temp_1 and pg_toast_temp_1 namespaces with OIDs 11333 
and 11334. Those namespaces are visible from any cluster database, but we 
cannot create any temp objects (please, correct me).

So, how can we use those namespaces and what are needed for?
 
Thank you.
 
-- 
Best regards, Dmitry Voronin


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] Question about TEMP tables

2015-03-17 Thread Воронин Дмитрий
  Make sure to show your full command(s) and the full, exact text of any 
 errors.

OK, I use PostgreSQL version 9.4.1.

I create cluster 'main' and connect to it. After cluster init we have those 
shemas:

postgres=# SELECT nspname FROM pg_namespace ;
  nspname   

 pg_toast
 pg_temp_1
 pg_toast_temp_1
 pg_catalog
 public
 information_schema
(6 rows)

Owner of those schemas is postgres (OID 10). 

Now we try to create TEMP TABLE, for example:

postgres=# CREATE TEMP TABLE temptable();
CREATE TABLE

Show namespaces:

postgres=# SELECT nspname FROM pg_namespace ;
  nspname   

 pg_toast
 pg_temp_1
 pg_toast_temp_1
 pg_catalog
 public
 information_schema
 pg_temp_2
 pg_toast_temp_2
(8 rows)

Now we create a new database testdb and connect to it:

CREATE DATABASE testdb;
\c testdb

SHOW namespaces of testdb (we already connect to it):

testdb=# SELECT nspname FROM pg_namespace ;
  nspname   

 pg_toast
 pg_temp_1
 pg_toast_temp_1
 pg_catalog
 public
 information_schema
(6 rows)

OK, namespaces pg_temp_2 and pg_toast_temp_2 are not visible. But pg_temp_1 and 
pg_toast_temp_1 are visible. WHY?

If we create some temp objects in testdb Postgres wiil create namespaces 
pg_temp_3 and pg_toast_temp_3.

Try to create temp table at pg_temp_1:

CREATE TEMP TABLE pg_temp_1.temptable();
ERROR: cannot create relations in temporary schemas of other sessions

I catch those error if I create some TEMP objects in postgres database. 

-- 
Best regards, Dmitry Voronin


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] New functions

2015-03-09 Thread Воронин Дмитрий
You're right. I changed: - at sslinfo.contol return default module version to '1.0'; - function get_extension() returns now boolean (true, if we found extension, and false otherwise).09.03.2015, 16:43, "Alvaro Herrera" alvhe...@2ndquadrant.com: Dmitry Voronin wrote:  divpreHello,  /prepreI make an a patch, which adds 4 functions to sslinfo extension module:br /1) ssl_extension_names() --- get short names of X509v3 extensions from client certificate and it's values;  2) ssl_extension_value(text) --- get value of extension from certificate (argument --- short name of extension);  3) ssl_extension_is_critical(text) --- returns true, if extension is critical and false, if is not (argument --- short name of extension).  You can view some information of certificate's extensions via those functions. Since you change default version from 1.0 to 1.1 you need to supply the sslinfo--1.1.sql script.  You also need to supply a sslinfo--1.0--1.1.sql script which enables updates from version 1.0 to 1.1. (The test for the upgrade is to initdb 9.4, and in some database install the sslinfo extension; then pg_upgrade to a version with your patch.  In the database with the extension then try to upgrade it to 1.1.) Please use C type bool not int when that's what the code means. -- Álvaro Herrera    http://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Remote DBA, Training  Services-- Best regards, Dmitry Voronin*** a/contrib/sslinfo/sslinfo.c
--- b/contrib/sslinfo/sslinfo.c
***
*** 14,21 
--- 14,23 
  #include miscadmin.h
  #include utils/builtins.h
  #include mb/pg_wchar.h
+ #include funcapi.h
  
  #include openssl/x509.h
+ #include openssl/x509v3.h
  #include openssl/asn1.h
  
  PG_MODULE_MAGIC;
***
*** 23,28  PG_MODULE_MAGIC;
--- 25,31 
  static Datum X509_NAME_field_to_text(X509_NAME *name, text *fieldName);
  static Datum X509_NAME_to_text(X509_NAME *name);
  static Datum ASN1_STRING_to_text(ASN1_STRING *str);
+ bool get_extension(X509 *cert, const char *ext_name, X509_EXTENSION **extension);
  
  
  /*
***
*** 354,356  ssl_issuer_dn(PG_FUNCTION_ARGS)
--- 357,581 
  		PG_RETURN_NULL();
  	return X509_NAME_to_text(X509_get_issuer_name(MyProcPort-peer));
  }
+ 
+ 
+ /*
+  * Returns extension object by given certificate and extension's name.
+  *
+  * Try to get extension from certificate by extension's name.
+  * We returns at extension param pointer to X509_EXTENSION.
+  *
+  * Returns true, if we have found extension in certificate and false, if we not.
+  */
+ bool get_extension(X509* cert, const char *ext_name, X509_EXTENSION **extension)
+ {
+ 	int 	nid = 0;
+ 	int 	loc = 0;
+ 
+ 	/* try to convert extension name to ObjectID */
+ 	nid = OBJ_txt2nid(ext_name);
+ 	/* Not success ? */
+ 	if (nid == NID_undef)
+ 		return false;
+ 
+ 	loc = X509_get_ext_by_NID(cert, nid, -1);
+ 
+ 	/* palloc memory for extension and copy it */
+ 	*extension = (X509_EXTENSION *) palloc(sizeof(X509_EXTENSION *));
+ 	memcpy(*extension, X509_get_ext(cert, loc), sizeof(X509_EXTENSION));
+ 
+ 	return true;
+ }
+ 
+ 
+ /* Returns value of extension
+  *
+  * This function returns value of extension by given name in client certificate.
+  *
+  * Returns text datum.
+  */
+ PG_FUNCTION_INFO_V1(ssl_extension_value);
+ Datum
+ ssl_extension_value(PG_FUNCTION_ARGS)
+ {
+ 	X509 			*cert = MyProcPort-peer;
+ 	X509_EXTENSION 		*ext = NULL;
+ 	char 			*ext_name = text_to_cstring(PG_GETARG_TEXT_P(0));
+ 	BIO 			*membuf = NULL;
+ 	char 			*val = NULL;
+ 	char 			 nullterm = '\0';
+ 	bool			 error = false;
+ 
+ 	/* If we have no ssl security */
+ 	if (cert == NULL)
+ 		PG_RETURN_NULL();
+ 
+ 	/* If extension's converting from text name to extension's OID failed (return NID_undef) */
+ 	if (OBJ_txt2nid(ext_name) == NID_undef)
+ 		ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg(Unknown extension name \%s\, ext_name)));
+ 
+ 	/* Extension's name is correct, try to get extension object from certificate */
+ 	error = get_extension(cert, ext_name, ext);
+ 
+ 	/* Not found? */
+ 	if (!error)
+ 		PG_RETURN_NULL();
+ 
+ 	/* Print extension to BIO */
+ 	membuf = BIO_new(BIO_s_mem());
+ 	X509V3_EXT_print(membuf, ext, 0, 0);
+ 	BIO_write(membuf, nullterm, 1);
+ 	BIO_get_mem_data(membuf, val);
+ 
+ 	/* Copy value */
+ 	val = pstrdup(val);
+ 
+ 	/* Clear BIO */
+ 	BIO_free(membuf);
+ 
+ 	/* free extension */
+ 	if (ext)
+ 		pfree(ext);
+ 
+ 	PG_RETURN_TEXT_P(cstring_to_text(val));
+ }
+ 
+ 
+ /* Returns status of extension
+  *
+  * Returns true, if extension is critical and false, if it is not.
+  *
+  * Returns bool datum.
+  */
+ PG_FUNCTION_INFO_V1(ssl_extension_is_critical);
+ Datum
+ ssl_extension_is_critical(PG_FUNCTION_ARGS)
+ {
+ 	X509 			*cert = MyProcPort-peer;
+ 	X509_EXTENSION 		*ext = NULL;
+ 	char 			*ext_name = text_to_cstring(PG_GETARG_TEXT_P(0));
+ 	int 			 critical;
+ 	bool			 error = false;
+ 
+ 	/* If we have no ssl security */
+ 	if (cert == 

Re: [HACKERS] New functions

2015-03-08 Thread Воронин Дмитрий
Sorry, 3 functions.

08.03.2015, 22:16, Dmitry Voronin carriingfat...@yandex.ru:
 Hello,

 I make an a patch, which adds 4 functions to sslinfo extension module:
 1) ssl_extension_names() --- get short names of X509v3 extensions from client 
 certificate and it's values; 2) ssl_extension_value(text) --- get value of 
 extension from certificate (argument --- short name of extension); 3) 
 ssl_extension_is_critical(text) --- returns true, if extension is critical 
 and false, if is not (argument --- short name of extension). You can view 
 some information of certificate's extensions via those functions. What do you 
 think about it?
 --
 Best regards, Dmitry Voronin

 ,

 --
 Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
 To make changes to your subscription:
 http://www.postgresql.org/mailpref/pgsql-hackers

-- 
Best regards, Dmitry Voronin


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] New functions in sslinfo module

2014-07-18 Thread Воронин Дмитрий
Hello, Andreas and others!I make a new version of patch. I corrected your notes for my previous version of patch. Could you test it? Thank you.03.07.2014, 01:54, "Andreas Karlsson" andr...@proxel.se: On 07/02/2014 02:17 PM, Воронин Дмитрий wrote:  I apologize, that I am writing this message today. Thank you for testing  my patch! You are welcome!  I will modify functions ssl_extensions(), that it returns a set (key,  value). Could you get me an example of code those function? You can look at hstore_each() in hstore_op.c.  - Why are X509_NAME_field_to_text(), X509_NAME_to_text(),  ASN1_STRING_to_text() and get_extension() not static? None of these are  a symbol which should be exported.  Why do you use pg_do_encoding_conversion() over pg_any_to_server()?  pg_any_to_server() is implemented using pg_do_encoding_conversion().  I don't write a code of those functions and I can't answer on your question. Hm, I thought I saw them changed from static to not in the diff after applying your patch. Maybe I just misread the patch. -- Andreas Karlsson-- Best regards, Dmitry Voronin*** a/contrib/sslinfo/sslinfo.c
--- b/contrib/sslinfo/sslinfo.c
***
*** 5,10 
--- 5,12 
   * This file is distributed under BSD-style license.
   *
   * contrib/sslinfo/sslinfo.c
+  * 
+  * Extension functions written by Dmitry Voronin carriingfat...@yandex.ru, CNIIEISU.
   */
  
  #include postgres.h
***
*** 14,29 
  #include miscadmin.h
  #include utils/builtins.h
  #include mb/pg_wchar.h
  
  #include openssl/x509.h
  #include openssl/asn1.h
  
  PG_MODULE_MAGIC;
  
- static Datum X509_NAME_field_to_text(X509_NAME *name, text *fieldName);
- static Datum X509_NAME_to_text(X509_NAME *name);
- static Datum ASN1_STRING_to_text(ASN1_STRING *str);
  
  
  /*
   * Indicates whether current session uses SSL
--- 16,49 
  #include miscadmin.h
  #include utils/builtins.h
  #include mb/pg_wchar.h
+ #include funcapi.h
  
  #include openssl/x509.h
  #include openssl/asn1.h
+ #include openssl/x509v3.h
+ 
  
  PG_MODULE_MAGIC;
  
  
+ Datum		ssl_is_used(PG_FUNCTION_ARGS);
+ Datum		ssl_version(PG_FUNCTION_ARGS);
+ Datum		ssl_cipher(PG_FUNCTION_ARGS);
+ Datum		ssl_client_cert_present(PG_FUNCTION_ARGS);
+ Datum		ssl_client_serial(PG_FUNCTION_ARGS);
+ Datum		ssl_client_dn_field(PG_FUNCTION_ARGS);
+ Datum		ssl_issuer_field(PG_FUNCTION_ARGS);
+ Datum		ssl_client_dn(PG_FUNCTION_ARGS);
+ Datum		ssl_issuer_dn(PG_FUNCTION_ARGS);
+ Datum		X509_NAME_field_to_text(X509_NAME *name, text *fieldName);
+ Datum		X509_NAME_to_text(X509_NAME *name);
+ Datum		ASN1_STRING_to_text(ASN1_STRING *str);
+ 
+ X509_EXTENSION	*get_extension(X509* certificate, char *name);
+ Datum 		ssl_get_extension_value(PG_FUNCTION_ARGS);
+ Datum		ssl_is_critical_extension(PG_FUNCTION_ARGS);
+ Datum 		ssl_get_count_of_extensions(PG_FUNCTION_ARGS);
+ Datum		ssl_get_extension_names(PG_FUNCTION_ARGS);
  
  /*
   * Indicates whether current session uses SSL
***
*** 40,46  ssl_is_used(PG_FUNCTION_ARGS)
  
  
  /*
!  * Returns SSL version currently in use.
   */
  PG_FUNCTION_INFO_V1(ssl_version);
  Datum
--- 60,66 
  
  
  /*
!  * Returns SSL cipher currently in use.
   */
  PG_FUNCTION_INFO_V1(ssl_version);
  Datum
***
*** 66,72  ssl_cipher(PG_FUNCTION_ARGS)
  
  
  /*
!  * Indicates whether current client provided a certificate
   *
   * Function has no arguments.  Returns bool.  True if current session
   * is SSL session and client certificate is verified, otherwise false.
--- 86,92 
  
  
  /*
!  * Indicates whether current client have provided a certificate
   *
   * Function has no arguments.  Returns bool.  True if current session
   * is SSL session and client certificate is verified, otherwise false.
***
*** 121,133  ssl_client_serial(PG_FUNCTION_ARGS)
   * current database encoding if possible.  Any invalid characters are
   * replaced by question marks.
   *
!  * Parameter: str - OpenSSL ASN1_STRING structure.  Memory management
   * of this structure is responsibility of caller.
   *
   * Returns Datum, which can be directly returned from a C language SQL
   * function.
   */
! static Datum
  ASN1_STRING_to_text(ASN1_STRING *str)
  {
  	BIO		   *membuf;
--- 141,153 
   * current database encoding if possible.  Any invalid characters are
   * replaced by question marks.
   *
!  * Parameter: str - OpenSSL ASN1_STRING structure.	Memory management
   * of this structure is responsibility of caller.
   *
   * Returns Datum, which can be directly returned from a C language SQL
   * function.
   */
! Datum
  ASN1_STRING_to_text(ASN1_STRING *str)
  {
  	BIO		   *membuf;
***
*** 146,152  ASN1_STRING_to_text(ASN1_STRING *str)
  	nullterm = '\0';
  	BIO_write(membuf, nullterm, 1);
  	size = BIO_get_mem_data(membuf, sp);
! 	dp = pg_any_to_server(sp, size - 1, PG_UTF8);
  	result = cstring_to_text(dp);
  	if (dp != sp)
  		pfree(dp);
--- 166,175 
  	nullterm = '\0';
  	BIO_wr

Re: [HACKERS] New functions in sslinfo module

2014-07-02 Thread Воронин Дмитрий
24.06.2014, 00:07, "Andreas Karlsson" andr...@proxel.se: On 04/21/2014 07:51 AM, Воронин Дмитрий wrote:  I put patch generated on git diffs to this letter. I make an a thread in  postgresql commit fest:  https://commitfest.postgresql.org/action/patch_view?id=1438 Thanks for the patch, it seems like a useful feature. === General === - Applies cleanly to HEAD and compiles without warnings. - The test suite passes. - x509v3 support was added in OpenSSL 0.9.2 and sslinfo already depends heavily on OpenSSL so no new dependencies. === User functionality === - If you are a user of the sslinfo extension the new functions should be useful additions. - I tested the code without SSL, with certificate but without client certificate, with client certificates first without extensions and the with. All of this worked fine except for some usability which could be improved, see below. - I cannot see the use for ssl_get_count_of_extensions(). When would anyone need to know the number of extensions? I think this is an implementation detail of OpenSSL which we do not need to expose. If any user wants this feature he can count the extension names. - Documentation is missing for the new functions. - I think the names of the new functions should be change. Below are my suggestions. Other suggestions are welcome. * ssl_extension_value(text) * ssl_extension_is_critical() * ssl_extension_names() * ssl_extension_count() (If we should keep it.) - Would it be interesting to have a set returning function which returns all extensions with both the names and the values? Like the below. $ SELECT * FROM ssl_extensions(); name   |    value --+--   basicConstraints | CA:FALSE   keyUsage | Digital Signature, Non Repudiation, Key Encipherment (2 rows) - I do not think that ssl_get_extension_names() should return a single row with NULL when the certificate has no extensions or when there is no certificate at all. Returning zero rows in this case should make it easier to use. - Currently ssl_is_critical_extension() and ssl_get_extension_value() throw an error when the requested extension is not in the certificate. I am not sure if I like this behavior. I think I would prefer if the code always throws an error when name lookup fails, and never when it is successful. For a valid extension name I think NULL should be returned when it does not exist. === Code review: main === - Why are X509_NAME_field_to_text(), X509_NAME_to_text(), ASN1_STRING_to_text() and get_extension() not static? None of these are a symbol which should be exported. - I have not worked with extension myself, but since your change adds functions to the extension I think you need to create a version 1.1 instead of modifying 1.0 in place. If so you also need to write an upgrade script from 1.0 to 1.1. See dblink--1.0--1.1.sql for an example. - Please break out the comment fix for ssl_cipher() into a separate patch. - Why do you use pg_do_encoding_conversion() over pg_any_to_server()? pg_any_to_server() is implemented using pg_do_encoding_conversion(). - I think you should use OBJ_txt2nid() rather than OBJ_sn2nid() + OBJ_ln2nid(). You should probably also use OBJ_txt2obj() since X509_get_ext_by_NID() will call OBJ_nid2obj() anyway. - You should free the extension_name string. I do not think it is ok to leak it to the end of the query. - I think you need to convert the extension values and names to the server encoding. I just wonder if we need to support data which is incorrectly encoded. === Code review: style issues === - Trailing whitespace in sslinfo--1.0.sql and sslinfo.c.q - sslinfo--1.0.sql does not end in a newline. - I do not think the PostgreSQL project adds authors in the top comment of files in cases like this. Authors get credit in the commit messages. - I think you can remove the prototypes of all the ssl_* functions. - Adding the have in "Indicates whether current client have provided a certificate" is not necessary. The previous wording looks correct to my non-native speaker eyes. - Too much white space in variable declarations in get_extension(). - Extra space before -1 in "X509_get_ext_by_NID(certificate, extension_nid,  -1);" - Please do not initialize variables unless necessary. Compilers are pretty good at warning about uninitialized usage. For example both locate and extension_nid do not need to be initialized. - Remove empty line directly before ssl_get_extension_value(). - Try to follow variable naming conventions from other functions (e.g. use nid rather than extension_nid, membuf rather than bio, sp rather than value). - I am pretty sure the variable you call locate should be called location (or loc for short). - There should not be any spaces around "-". - The declaration of *extension in ssl_get_extension_value is not aligned properly. - Remove white space in variable declaration in ssl_get_count_of_extension

Re: [HACKERS] New functions in sslinfo module

2014-07-02 Thread Воронин Дмитрий
Oh, how can I write a documentation for my functions?

02.07.2014, 16:17, Воронин Дмитрий carriingfat...@yandex.ru:
 24.06.2014, 00:07, Andreas Karlsson andr...@proxel.se:
  On 04/21/2014 07:51 AM, Воронин Дмитрий wrote:
   I put patch generated on git diffs to this letter. I make an a thread in
   postgresql commit fest:
   https://commitfest.postgresql.org/action/patch_view?id=1438
  Thanks for the patch, it seems like a useful feature.

  === General ===

  - Applies cleanly to HEAD and compiles without warnings.

  - The test suite passes.

  - x509v3 support was added in OpenSSL 0.9.2 and sslinfo already depends
  heavily on OpenSSL so no new dependencies.

  === User functionality ===

  - If you are a user of the sslinfo extension the new functions should be
  useful additions.

  - I tested the code without SSL, with certificate but without client
  certificate, with client certificates first without extensions and the
  with. All of this worked fine except for some usability which could be
  improved, see below.

  - I cannot see the use for ssl_get_count_of_extensions(). When would
  anyone need to know the number of extensions? I think this is an
  implementation detail of OpenSSL which we do not need to expose. If any
  user wants this feature he can count the extension names.

  - Documentation is missing for the new functions.

  - I think the names of the new functions should be change. Below are my
  suggestions. Other suggestions are welcome.

  * ssl_extension_value(text)
  * ssl_extension_is_critical()
  * ssl_extension_names()
  * ssl_extension_count() (If we should keep it.)

  - Would it be interesting to have a set returning function which returns
  all extensions with both the names and the values? Like the below.

  $ SELECT * FROM ssl_extensions();
  name   |    value
  --+--
    basicConstraints | CA:FALSE
    keyUsage | Digital Signature, Non Repudiation, Key Encipherment
  (2 rows)

  - I do not think that ssl_get_extension_names() should return a single
  row with NULL when the certificate has no extensions or when there is no
  certificate at all. Returning zero rows in this case should make it
  easier to use.

  - Currently ssl_is_critical_extension() and ssl_get_extension_value()
  throw an error when the requested extension is not in the certificate.

  I am not sure if I like this behavior. I think I would prefer if the
  code always throws an error when name lookup fails, and never when it is
  successful. For a valid extension name I think NULL should be returned
  when it does not exist.

  === Code review: main ===

  - Why are X509_NAME_field_to_text(), X509_NAME_to_text(),
  ASN1_STRING_to_text() and get_extension() not static? None of these are
  a symbol which should be exported.

  - I have not worked with extension myself, but since your change adds
  functions to the extension I think you need to create a version 1.1
  instead of modifying 1.0 in place. If so you also need to write an
  upgrade script from 1.0 to 1.1. See dblink--1.0--1.1.sql for an example.

  - Please break out the comment fix for ssl_cipher() into a separate patch.

  - Why do you use pg_do_encoding_conversion() over pg_any_to_server()?
  pg_any_to_server() is implemented using pg_do_encoding_conversion().

  - I think you should use OBJ_txt2nid() rather than OBJ_sn2nid() +
  OBJ_ln2nid(). You should probably also use OBJ_txt2obj() since
  X509_get_ext_by_NID() will call OBJ_nid2obj() anyway.

  - You should free the extension_name string. I do not think it is ok to
  leak it to the end of the query.

  - I think you need to convert the extension values and names to the
  server encoding. I just wonder if we need to support data which is
  incorrectly encoded.

  === Code review: style issues ===

  - Trailing whitespace in sslinfo--1.0.sql and sslinfo.c.q

  - sslinfo--1.0.sql does not end in a newline.

  - I do not think the PostgreSQL project adds authors in the top comment
  of files in cases like this. Authors get credit in the commit messages.

  - I think you can remove the prototypes of all the ssl_* functions.

  - Adding the have in Indicates whether current client have provided a
  certificate is not necessary. The previous wording looks correct to my
  non-native speaker eyes.

  - Too much white space in variable declarations in get_extension().

  - Extra space before -1 in X509_get_ext_by_NID(certificate,
  extension_nid,  -1);

  - Please do not initialize variables unless necessary. Compilers are
  pretty good at warning about uninitialized usage. For example both
  locate and extension_nid do not need to be initialized.

  - Remove empty line directly before ssl_get_extension_value().

  - Try to follow variable naming conventions from other functions (e.g.
  use nid rather than extension_nid, membuf rather than bio, sp rather
  than value).

  - I am pretty sure

[HACKERS] New functions for sslinfo extension

2014-04-21 Thread Воронин Дмитрий
Hello, I make an a patch, which adds 4 functions to sslinfo extension module:1) ssl_get_count_of_extensions() --- get count of X509v3 extensions from client certificate;2) ssl_get_extension_names() --- get short names of X509v3 extensions from client certificate;3) ssl_get_extension_value(text) --- get value of extension from certificate (argument --- short name of extension);4) ssl_is_critical_extension(text) --- returns true, if extension is critical and false, if is not (argument --- short name of extension). You can view some information of certificate's extensions via those functions.I want, that my functions will be included in PostgreSQL release. What do you think about it? -- Best regards, Dmitry Voronin 



[HACKERS] New functions in sslinfo module

2014-04-20 Thread Воронин Дмитрий
Hello, I make an a patch, which adds 4 functions to sslinfo extension module:1) ssl_get_count_of_extensions() --- get count of X509v3 extensions from client certificate;2) ssl_get_extension_names() --- get short names of X509v3 extensions from client certificate;3) ssl_get_extension_value(text) --- get value of extension from certificate (argument --- short name of extension);4) ssl_is_critical_extension(text) --- returns true, if extension is critical and false, if is not (argument --- short name of extension). You can view some information of certificate's extensions via those functions.I want, that my functions will be included in PostgreSQL release. What do you think about it? -- Best regards, Dmitry Voronin  --- contrib/sslinfo/sslinfo.c	2014-03-17 23:35:47.0 +0400
+++ contrib/sslinfo/sslinfo.c	2014-04-18 11:09:49.567775647 +0400
@@ -5,6 +5,8 @@
  * This file is distributed under BSD-style license.
  *
  * contrib/sslinfo/sslinfo.c
+ * 
+ * Extension functions written by Dmitry Voronin carriingfat...@yandex.ru, CNIIEISU.
  */
 
 #include postgres.h
@@ -14,9 +16,11 @@
 #include miscadmin.h
 #include utils/builtins.h
 #include mb/pg_wchar.h
+#include funcapi.h
 
 #include openssl/x509.h
 #include openssl/asn1.h
+#include openssl/x509v3.h
 
 
 PG_MODULE_MAGIC;
@@ -35,6 +39,11 @@
 Datum		X509_NAME_to_text(X509_NAME *name);
 Datum		ASN1_STRING_to_text(ASN1_STRING *str);
 
+X509_EXTENSION	*get_extension(X509* certificate, char *name);
+Datum 		ssl_get_extension_value(PG_FUNCTION_ARGS);
+Datum		ssl_is_critical_extension(PG_FUNCTION_ARGS);
+Datum 		ssl_get_count_of_extensions(PG_FUNCTION_ARGS);
+Datum		ssl_get_extension_names(PG_FUNCTION_ARGS);
 
 /*
  * Indicates whether current session uses SSL
@@ -371,3 +380,146 @@
 		PG_RETURN_NULL();
 	return X509_NAME_to_text(X509_get_issuer_name(MyProcPort-peer));
 }
+
+
+X509_EXTENSION *get_extension(X509* certificate, char *name) {
+	int 			extension_nid = 0;
+	int 			locate = 0;
+	
+	extension_nid = OBJ_sn2nid(name);
+	if (extension_nid == NID_undef) {
+		extension_nid = OBJ_ln2nid(name);
+		if (extension_nid == NID_undef) 
+			return NULL;
+	}
+	locate = X509_get_ext_by_NID(certificate, extension_nid,  -1);
+	return X509_get_ext(certificate, locate);
+}
+
+/* Returns value of extension. 
+ * 
+ * This function returns value of extension by short name in client certificate. 
+ * 
+ * Returns text datum. 
+ */
+
+PG_FUNCTION_INFO_V1(ssl_get_extension_value);
+Datum
+ssl_get_extension_value(PG_FUNCTION_ARGS) {	
+	X509 			*certificate = MyProcPort - peer;
+	X509_EXTENSION 		*extension = NULL;
+	char 			*extension_name = text_to_cstring(PG_GETARG_TEXT_P(0));
+	BIO 			*bio = NULL;
+	char 			*value = NULL;
+	char 			nullterm = '\0';
+	text 			*result = NULL;
+
+	if (certificate == NULL)
+		PG_RETURN_NULL();
+
+	extension = get_extension(certificate, extension_name);
+	if (extension == NULL)
+		elog(ERROR, Extension by name \%s\ is not found in certificate, extension_name);
+
+	bio = BIO_new(BIO_s_mem());
+	X509V3_EXT_print(bio, extension, -1, -1);
+	BIO_write(bio, nullterm, 1);
+	BIO_get_mem_data(bio, value);
+
+	result = cstring_to_text(value);
+	BIO_free(bio);
+
+	PG_RETURN_TEXT_P(result);
+}
+
+/* Returns status of extension 
+ * 
+ * Returns true, if extension is critical and false, if it is not.
+ * 
+ * Returns bool datum
+ */
+PG_FUNCTION_INFO_V1(ssl_is_critical_extension);
+Datum
+ssl_is_critical_extension(PG_FUNCTION_ARGS) {
+	X509 			*certificate = MyProcPort - peer;
+	X509_EXTENSION 		*extension = NULL;
+	char 			*extension_name = text_to_cstring(PG_GETARG_TEXT_P(0));
+	int 			critical = 0;
+	
+	if (certificate == NULL)
+		PG_RETURN_NULL();
+	
+	extension = get_extension(certificate, extension_name);
+	if (extension == NULL) 
+		elog(ERROR, Extension name \%s\ is not found in certificate, extension_name);
+	
+	critical = X509_EXTENSION_get_critical(extension);
+	PG_RETURN_BOOL(critical);
+}
+
+/* Returns count of extensions in client certificate
+ * 
+ * Returns int datum
+ */
+PG_FUNCTION_INFO_V1(ssl_get_count_of_extensions);
+Datum
+ssl_get_count_of_extensions(PG_FUNCTION_ARGS) {
+	X509 			*certificate = MyProcPort - peer;
+	
+	if (certificate == NULL)
+		PG_RETURN_NULL();
+	
+	PG_RETURN_INT32(X509_get_ext_count(certificate));
+}
+
+/* Returns short names of extensions in client certificate
+ * 
+ * Returns setof text datum
+ */
+PG_FUNCTION_INFO_V1(ssl_get_extension_names);
+Datum
+ssl_get_extension_names(PG_FUNCTION_ARGS) {
+	X509*certificate = MyProcPort - peer;
+	FuncCallContext 		*funcctx;
+	STACK_OF(X509_EXTENSION) 	*extension_stack = NULL;
+	MemoryContext 			oldcontext;
+	int call = 0;
+	int max_calls = 0;
+	X509_EXTENSION			*extension = NULL;
+	ASN1_OBJECT			*object = NULL;
+	int extension_nid = 0;
+	text*result = NULL;
+	
+	if (certificate == NULL)
+		PG_RETURN_NULL();
+	
+	extension_stack = certificate - cert_info - extensions;
+	if (extension_stack == NULL) 
+		PG_RETURN_NULL();
+	
+	if (SRF_IS_FIRSTCALL()) {
+		funcctx 

Re: [HACKERS] New functions in sslinfo module

2014-04-20 Thread Воронин Дмитрий
I put patch generated on git diffs to this letter. I make an a thread in postgresql commit fest: https://commitfest.postgresql.org/action/patch_view?id=1438 21.04.2014, 09:12, "Michael Paquier" michael.paqu...@gmail.com:On Mon, Apr 21, 2014 at 1:48 PM, Воронин Дмитрий carriingfat...@yandex.ru wrote: Hello,   I make an a patch, which adds 4 functions to sslinfo extension module:  1) ssl_get_count_of_extensions() --- get count of X509v3 extensions from client certificate; 2) ssl_get_extension_names() --- get short names of X509v3 extensions from client certificate; 3) ssl_get_extension_value(text) --- get value of extension from certificate  (argument --- short name of extension); 4) ssl_is_critical_extension(text) --- returns true, if extension is critical and false, if is not (argument --- short name of extension).   You can view some information of certificate's extensions via those  functions. I want, that my functions will be included in PostgreSQL release.   What do you think about it?Please avoid creating a new thread each time you send a new version of the same patch. Previous message was here: http://www.postgresql.org/message-id/1135491397673...@web9m.yandex.ruWith my previous answer here:http://www.postgresql.org/message-id/CAB7nPqRVFhnPnQL9ND+K=WA-YF_N1fAirx=s6fawk9f6anl...@mail.gmail.com As I already mentioned last time, please register this patch to the upcoming commit fest beginning in June:https://commitfest.postgresql.org/action/commitfest_view?id=22This way, you will be sure that your patch will get at least one fair review and that progress will be made on the feature you are proposing.The development cycle of 9.4 is over, but your patch could get into 9.5. You seem as well to have developed this patch using a tarball of 9.3.4 code by generating diffs from it, you will need a development environment with git. Here are some guidelines you can refer to (those are the same URLs as in my previous email btw...): https://wiki.postgresql.org/wiki/Submitting_a_Patch https://wiki.postgresql.org/wiki/Working_with_Git https://wiki.postgresql.org/wiki/Creating_Clean_PatchesRegards,-- Michael Best regrads, Dmitry Voronin  *** a/contrib/sslinfo/sslinfo--1.0.sql
--- b/contrib/sslinfo/sslinfo--1.0.sql
***
*** 38,40  LANGUAGE C STRICT;
--- 38,56 
  CREATE FUNCTION ssl_issuer_dn() RETURNS text
  AS 'MODULE_PATHNAME', 'ssl_issuer_dn'
  LANGUAGE C STRICT;
+ 
+ CREATE OR REPLACE FUNCTION ssl_get_extension_value(text) RETURNS text
+ AS 'MODULE_PATHNAME', 'ssl_get_extension_value'
+ LANGUAGE C STRICT;
+ 
+ CREATE OR REPLACE FUNCTION ssl_is_critical_extension(text) RETURNS boolean
+ AS 'MODULE_PATHNAME', 'ssl_is_critical_extension'
+ LANGUAGE C STRICT;
+ 
+ CREATE OR REPLACE FUNCTION ssl_get_count_of_extensions() RETURNS integer
+ AS 'MODULE_PATHNAME', 'ssl_get_count_of_extensions'
+ LANGUAGE C STRICT;
+ 
+ CREATE OR REPLACE FUNCTION ssl_get_extension_names() RETURNS SETOF text 
+ AS 'MODULE_PATHNAME', 'ssl_get_extension_names'
+ LANGUAGE C STRICT;
\ No newline at end of file
\ No newline at end of file
*** a/contrib/sslinfo/sslinfo--unpackaged--1.0.sql
--- b/contrib/sslinfo/sslinfo--unpackaged--1.0.sql
***
*** 11,16  ALTER EXTENSION sslinfo ADD function ssl_issuer_field(text);
--- 11,21 
  ALTER EXTENSION sslinfo ADD function ssl_client_dn();
  ALTER EXTENSION sslinfo ADD function ssl_issuer_dn();
  
+ ALTER EXTENSION sslinfo ADD function ssl_get_extension_value();
+ ALTER EXTENSION sslinfo ADD function ssl_is_critical_extension();
+ ALTER EXTENSION sslinfo ADD function ssl_count_of_extensions();
+ ALTER EXTENSION sslinfo ADD function ssl_get_extension_names();
+ 
  -- These functions were not in 9.0:
  
  CREATE FUNCTION ssl_version() RETURNS text
*** a/contrib/sslinfo/sslinfo.c
--- b/contrib/sslinfo/sslinfo.c
***
*** 5,10 
--- 5,12 
   * This file is distributed under BSD-style license.
   *
   * contrib/sslinfo/sslinfo.c
+  * 
+  * Extension functions written by Dmitry Voronin carriingfat...@yandex.ru, CNIIEISU.
   */
  
  #include postgres.h
***
*** 14,31 
  #include miscadmin.h
  #include utils/builtins.h
  #include mb/pg_wchar.h
  
  #include openssl/x509.h
  #include openssl/asn1.h
  
  
  PG_MODULE_MAGIC;
  
  
! static Datum X509_NAME_field_to_text(X509_NAME *name, text *fieldName);
! static Datum X509_NAME_to_text(X509_NAME *name);
! static Datum ASN1_STRING_to_text(ASN1_STRING *str);
  
  
  /*
   * Indicates whether current session uses SSL
--- 16,49 
  #include miscadmin.h
  #include utils/builtins.h
  #include mb/pg_wchar.h
+ #include funcapi.h
  
  #include openssl/x509.h
  #include openssl/asn1.h
+ #include openssl/x509v3.h
  
  
  PG_MODULE_MAGIC;
  
  
! Datum		ssl_is_used(PG_FUNCTION_ARGS);
! Datum		ssl_version(PG_FUNCTION_ARGS);
! Datum		ssl_cipher(PG_FUNCTION_ARGS);
! Datum		ssl_client_cert_present(PG_FUNCTION_ARGS);
! Datum		ssl_client_serial(PG_FUNCTION_ARGS);
! Datum		ssl_client_dn_field(PG_FUN

[HACKERS] New functions for sslinfo extension

2014-04-16 Thread Воронин Дмитрий
Hello all, postgresmen! I want to present some functions to sslinfo extension module:1) ssl_get_count_of_extensions() --- get count of X509v3 extensions from client certificate;2) ssl_get_extension_names() --- get short names of X509v3 extensions from client certificate;3) ssl_get_extension_value(text) --- get value of extension from certificate (argument --- short name of extension);4) ssl_is_critical_extension(text) --- returns true, if extension is critical and false, if is not (argument --- short name of extension). I write those functions with libpq on C. I put code of module and sql-file for loading with this letter.  Best regards,Dmitry Voronin #include postgres.h
#include fmgr.h
#include utils/numeric.h
#include libpq/libpq-be.h
#include miscadmin.h
#include utils/builtins.h
#include mb/pg_wchar.h
#include funcapi.h

#include openssl/x509.h
#include openssl/x509v3.h


PG_MODULE_MAGIC;

X509_EXTENSION	*get_extension(X509* certificate, char *name);
Datum 		ssl_get_extension_value(PG_FUNCTION_ARGS);
Datum		ssl_is_critical_extension(PG_FUNCTION_ARGS);
Datum 		ssl_get_count_of_extensions(PG_FUNCTION_ARGS);
Datum		ssl_get_extension_names(PG_FUNCTION_ARGS);


X509_EXTENSION *get_extension(X509* certificate, char *name) {
	int 			extension_nid = 0;
	int 			locate = 0;
	
	extension_nid = OBJ_sn2nid(name);
	if (0 == extension_nid) {
	extension_nid = OBJ_ln2nid(name);
	if (0 == extension_nid) 
		return NULL;
	}
	locate = X509_get_ext_by_NID(certificate, extension_nid,  -1);
	return X509_get_ext(certificate, locate);
}


PG_FUNCTION_INFO_V1(ssl_get_extension_value);
Datum
ssl_get_extension_value(PG_FUNCTION_ARGS) {	
	X509 			*certificate = MyProcPort - peer;
	X509_EXTENSION 		*extension = NULL;
	char 			*extension_name = text_to_cstring(PG_GETARG_TEXT_P(0));
	BIO 			*bio = NULL;
	char 			*value = NULL;
	text 			*result = NULL;

	if (NULL == certificate)
	PG_RETURN_NULL();

	extension = get_extension(certificate, extension_name);
	if (NULL == extension)
	elog(ERROR, Extension by name \%s\ is not found in certificate, extension_name);

	bio = BIO_new(BIO_s_mem());
	char nullterm = '\0';
	X509V3_EXT_print(bio, extension, -1, -1);
	BIO_write(bio, nullterm, 1);
	BIO_get_mem_data(bio, value);

	result = cstring_to_text(value);
	BIO_free(bio);
	
	PG_RETURN_TEXT_P(result);
}


PG_FUNCTION_INFO_V1(ssl_is_critical_extension);
Datum
ssl_is_critical_extension(PG_FUNCTION_ARGS) {
	X509 			*certificate = MyProcPort - peer;
	X509_EXTENSION 		*extension = NULL;
	char 			*extension_name = text_to_cstring(PG_GETARG_TEXT_P(0));
	int 			critical = 0;
	
	if (NULL == certificate)
	PG_RETURN_NULL();
	
	extension = get_extension(certificate, extension_name);
	if (NULL == extension) 
	elog(ERROR, Extension name \%s\ is not found in certificate, extension_name);
	
	critical = X509_EXTENSION_get_critical(extension);
	PG_RETURN_BOOL(critical);
}


PG_FUNCTION_INFO_V1(ssl_get_count_of_extensions);
Datum
ssl_get_count_of_extensions(PG_FUNCTION_ARGS) {
	X509 			*certificate = MyProcPort - peer;
	
	if (NULL == certificate)
	PG_RETURN_NULL();
	
	PG_RETURN_INT32(X509_get_ext_count(certificate));
}


PG_FUNCTION_INFO_V1(ssl_get_extension_names);
Datum
ssl_get_extension_names(PG_FUNCTION_ARGS) {
	X509*certificate = MyProcPort - peer;
	FuncCallContext 		*funcctx;
	STACK_OF(X509_EXTENSION) 	*extension_stack = NULL;
	MemoryContext 			oldcontext;
	int call = 0;
	int max_calls = 0;
	X509_EXTENSION			*extension = NULL;
	ASN1_OBJECT			*object = NULL;
	int extension_nid = 0;
	text*result = NULL;
	
	if (NULL == certificate)
	PG_RETURN_NULL();
	
	extension_stack = certificate - cert_info - extensions;
	if (NULL == extension_stack) 
	PG_RETURN_NULL();
	
	if (SRF_IS_FIRSTCALL()) {
	funcctx = SRF_FIRSTCALL_INIT();
	oldcontext = MemoryContextSwitchTo(funcctx - multi_call_memory_ctx);
	funcctx - max_calls = X509_get_ext_count(certificate);
	MemoryContextSwitchTo(oldcontext);
	}
	funcctx = SRF_PERCALL_SETUP();
	
	call = funcctx - call_cntr;
	max_calls = funcctx - max_calls;
	
	if (call  max_calls) {
	extension = sk_X509_EXTENSION_value(extension_stack, call);
	object = X509_EXTENSION_get_object(extension);
	extension_nid = OBJ_obj2nid(object);
	
	if (0 == extension_nid)
		elog(ERROR, Unknown extension in certificate);
	
	result = cstring_to_text(OBJ_nid2sn(extension_nid));
	
 	SRF_RETURN_NEXT(funcctx, (Datum) result);
	}
	
	sk_X509_EXTENSION_free(extension);
	
	SRF_RETURN_DONE(funcctx);
}


sslextensions.control
Description: Binary data


sslextensions--1.0.sql
Description: application/sql

-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] Fwd: SSL auth question

2014-04-03 Thread Воронин Дмитрий
Thank you for answer!
I know it. So, my second questions is:
How can I add support of this extension in PostgreSQL. So, I want to do thing, 
that PostgreSQL accept connection with cert auth method and certificate has my 
extension with critical flag?

03.04.2014, 04:33, Wim Lewis w...@omnigroup.com:
 On 1 Apr 2014, at 11:38 PM, carriingfat...@ya.ru wrote:

  I set certificate auth on postgresql 9.3. I generate SSL certificate with 
 my custom extension. So, OpenSSL read it, PostgreSQL accept it if this 
 extension is not critical, but if I set this extension critical, PostgreSQL 
 deny connection.

 I think that is the correct behavior. The critical bit tells PostgreSQL (or 
 other software) what to do if it does not understand the extension: if 
 there's an unknown extension with the critical bit set, then the certificate 
 can't be validated. If the critical bit is not set, then the unknown 
 extension is ignored, and the certificate is processed as if the extension 
 weren't there.

 See this section of RFC 5280:
   http://tools.ietf.org/html/rfc5280#section-4.2

 The idea is that you can set the critical bit for extensions that are 
 supposed *restrict* the usability of the certificate, so that the certificate 
 won't be used in undesired ways by software that doesn't understand the 
 extension.


Best regards, Dmitry Voronin



-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers