I am trying to connect to PostgreSQL database from my c# application like so:
NpgsqlConnection MyConnection = new
NpgsqlConnection("Server=localhost;Port=5432;User Id=postgres;Password=mypassword;Database=mydatabase;");
try
{
MyConnection.Open();
}
catch (NpgsqlException pe)
{
//Code "28P01" = user name or password is wrong
// server ip or port is wrong
}
the question is : NpgsqlException.code does not differentiate between the following conditions:
- server ip /port number is wrong
- user name and password combination is wrong
Code «28P01» is returned in both cases. obviously Npgsql can see that the server is there and responding with some data indicating bad user name or password (condition #2 above) or nobody seem to be there (condition #1 above)
how can i differentiate between those 2 cases in my code?
NASSER
5,9007 gold badges38 silver badges57 bronze badges
asked Sep 5, 2015 at 0:11
2
with Npgsql v 3.0.2.0 (not sure about older versions) if the IP/hostname is wrong an Exception with code =-2146233083 with be thrown. if however the IP/hostname is correct but the port number is wrong Exception with code= -2147467259 with be thrown. if the IP/port is correct but username /password is wrong a NpgsqlException with code = «28P01» will be thrown.
answered Sep 5, 2015 at 11:37
EKanadilyEKanadily
3,8293 gold badges35 silver badges33 bronze badges
1
You’re probably using Npgsql 2.x; the new Npgsql 3.x throws NpgsqlException only when errors are received from a PostgreSQL server. Network connection errors are raised as SocketException etc. You’re encouraged to upgrade.
By the way: I couldn’t reproduce your exact findings even with Npgql 2.x, connecting to a wrong port or a wrong IP resulted in an NpgsqlException with Code being an empty string, not 28P01.
answered Sep 5, 2015 at 7:28
Shay RojanskyShay Rojansky
15.4k2 gold badges40 silver badges70 bronze badges
3
I am trying to connect to PostgreSQL database from my c# application like so:
NpgsqlConnection MyConnection = new
NpgsqlConnection("Server=localhost;Port=5432;User Id=postgres;Password=mypassword;Database=mydatabase;");
try
{
MyConnection.Open();
}
catch (NpgsqlException pe)
{
//Code "28P01" = user name or password is wrong
// server ip or port is wrong
}
the question is : NpgsqlException.code does not differentiate between the following conditions:
- server ip /port number is wrong
- user name and password combination is wrong
Code «28P01» is returned in both cases. obviously Npgsql can see that the server is there and responding with some data indicating bad user name or password (condition #2 above) or nobody seem to be there (condition #1 above)
how can i differentiate between those 2 cases in my code?
NASSER
5,9007 gold badges38 silver badges57 bronze badges
asked Sep 5, 2015 at 0:11
2
with Npgsql v 3.0.2.0 (not sure about older versions) if the IP/hostname is wrong an Exception with code =-2146233083 with be thrown. if however the IP/hostname is correct but the port number is wrong Exception with code= -2147467259 with be thrown. if the IP/port is correct but username /password is wrong a NpgsqlException with code = «28P01» will be thrown.
answered Sep 5, 2015 at 11:37
EKanadilyEKanadily
3,8293 gold badges35 silver badges33 bronze badges
1
You’re probably using Npgsql 2.x; the new Npgsql 3.x throws NpgsqlException only when errors are received from a PostgreSQL server. Network connection errors are raised as SocketException etc. You’re encouraged to upgrade.
By the way: I couldn’t reproduce your exact findings even with Npgql 2.x, connecting to a wrong port or a wrong IP resulted in an NpgsqlException with Code being an empty string, not 28P01.
answered Sep 5, 2015 at 7:28
Shay RojanskyShay Rojansky
15.4k2 gold badges40 silver badges70 bronze badges
3
How to handle authentication in a RESTful Client-Server architecture is a matter of debate.
Commonly, it can be achieved, in the SOA over HTTP world via:
- HTTP basic auth over HTTPS;
- Cookies and session management;
- Token in HTTP headers (e.g. OAuth 2.0 + JWT);
- Query Authentication with additional signature parameters.
You’ll have to adapt, or even better mix those techniques, to match your software architecture at best.
Each authentication scheme has its own PROs and CONs, depending on the purpose of your security policy and software architecture.
HTTP basic auth over HTTPS
This first solution, based on the standard HTTPS protocol, is used by most web services.
GET /spec.html HTTP/1.1
Host: www.example.org
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
It’s easy to implement, available by default on all browsers, but has some known drawbacks, like the awful authentication window displayed on the Browser, which will persist (there is no LogOut-like feature here), some server-side additional CPU consumption, and the fact that the user-name and password are transmitted (over HTTPS) into the Server (it should be more secure to let the password stay only on the client side, during keyboard entry, and be stored as secure hash on the Server).
We may use Digest Authentication, but it requires also HTTPS, since it is vulnerable to MiM or Replay attacks, and is specific to HTTP.
Session via Cookies
To be honest, a session managed on the Server is not truly Stateless.
One possibility could be to maintain all data within the cookie content. And, by design, the cookie is handled on the Server side (Client, in fact, does even not try to interpret this cookie data: it just hands it back to the server on each successive request). But this cookie data is application state data, so the client should manage it, not the server, in a pure Stateless world.
GET /spec.html HTTP/1.1
Host: www.example.org
Cookie: theme=light; sessionToken=abc123
The cookie technique itself is HTTP-linked, so it’s not truly RESTful, which should be protocol-independent, IMHO. It is vulnerable to MiM or Replay attacks.
Granted via Token (OAuth2)
An alternative is to put a token within the HTTP headers so that the request is authenticated. This is what OAuth 2.0 does, for instance. See the RFC 6749:
GET /resource/1 HTTP/1.1
Host: example.com
Authorization: Bearer mF_9.B5f-4.1JqM
In short, this is very similar to a cookie and suffers to the same issues: not stateless, relying on HTTP transmission details, and subject to a lot of security weaknesses — including MiM and Replay — so is to be used only over HTTPS. Typically, a JWT is used as a token.
Query Authentication
Query Authentication consists in signing each RESTful request via some additional parameters on the URI. See this reference article.
It was defined as such in this article:
All REST queries must be authenticated by signing the query parameters
sorted in lower-case, alphabetical order using the private credential
as the signing token. Signing should occur before URL encoding the
query string.
This technique is perhaps the more compatible with a Stateless architecture, and can also be implemented with a light session management (using in-memory sessions instead of DB persistence).
For instance, here is a generic URI sample from the link above:
GET /object?apiKey=Qwerty2010
should be transmitted as such:
GET /object?timestamp=1261496500&apiKey=Qwerty2010&signature=abcdef0123456789
The string being signed is /object?apikey=Qwerty2010×tamp=1261496500 and the signature is the SHA256 hash of that string using the private component of the API key.
Server-side data caching can be always available. For instance, in our framework, we cache the responses at the SQL level, not at the URI level. So adding this extra parameter doesn’t break the cache mechanism.
See this article for some details about RESTful authentication in our client-server ORM/SOA/MVC framework, based on JSON and REST. Since we allow communication not only over HTTP/1.1, but also named pipes or GDI messages (locally), we tried to implement a truly RESTful authentication pattern, and not rely on HTTP specificity (like header or cookies).
Later Note: adding a signature in the URI can be seen as bad practice (since for instance it will appear in the http server logs) so it has to be mitigated, e.g. by a proper TTL to avoid replays. But if your http logs are compromised, you will certainly have bigger security problems.
In practice, the upcoming MAC Tokens Authentication for OAuth 2.0 may be a huge improvement in respect to the «Granted by Token» current scheme. But this is still a work in progress and is tied to HTTP transmission.
Conclusion
It’s worth concluding that REST is not only HTTP-based, even if, in practice, it’s also mostly implemented over HTTP. REST can use other communication layers. So a RESTful authentication is not just a synonym of HTTP authentication, whatever Google answers. It should even not use the HTTP mechanism at all but shall be abstracted from the communication layer. And if you use HTTP communication, thanks to the Let’s Encrypt initiative there is no reason not to use proper HTTPS, which is required in addition to any authentication scheme.
The following steps work for a fresh install of postgres 9.1 on Ubuntu 12.04. (Worked for postgres 9.3.9 on Ubuntu 14.04 too.)
By default, postgres creates a user named ‘postgres’. We log in as her, and give her a password.
$ sudo -u postgres psql
\password
Enter password: ...
...
Logout of psql by typing \q or ctrl+d. Then we connect as ‘postgres’. The -h localhost part is important: it tells the psql client that we wish to connect using a TCP connection (which is configured to use password authentication), and not by a PEER connection (which does not care about the password).
$ psql -U postgres -h localhost
00000successful_completion01000warning0100Cdynamic_result_sets_returned01008implicit_zero_bit_padding01003null_value_eliminated_in_set_function01007privilege_not_granted01006privilege_not_revoked01004string_data_right_truncation01P01deprecated_feature02000no_data02001no_additional_dynamic_result_sets_returned03000sql_statement_not_yet_complete08000connection_exception08003connection_does_not_exist08006connection_failure08001sqlclient_unable_to_establish_sqlconnection08004sqlserver_rejected_establishment_of_sqlconnection08007transaction_resolution_unknown08P01protocol_violation09000triggered_action_exception0A000feature_not_supported0B000invalid_transaction_initiation0F000locator_exception0F001invalid_locator_specification0L000invalid_grantor0LP01invalid_grant_operation0P000invalid_role_specification0Z000diagnostics_exception0Z002stacked_diagnostics_accessed_without_active_handler20000case_not_found21000cardinality_violation22000data_exception2202Earray_subscript_error22021character_not_in_repertoire22008datetime_field_overflow22012division_by_zero22005error_in_assignment2200Bescape_character_conflict22022indicator_overflow22015interval_field_overflow2201Einvalid_argument_for_logarithm22014invalid_argument_for_ntile_function22016invalid_argument_for_nth_value_function2201Finvalid_argument_for_power_function2201Ginvalid_argument_for_width_bucket_function22018invalid_character_value_for_cast22007invalid_datetime_format22019invalid_escape_character2200Dinvalid_escape_octet22025invalid_escape_sequence22P06nonstandard_use_of_escape_character22010invalid_indicator_parameter_value22023invalid_parameter_value22013invalid_preceding_or_following_size2201Binvalid_regular_expression2201Winvalid_row_count_in_limit_clause2201Xinvalid_row_count_in_result_offset_clause2202Hinvalid_tablesample_argument2202Ginvalid_tablesample_repeat22009invalid_time_zone_displacement_value2200Cinvalid_use_of_escape_character2200Gmost_specific_type_mismatch22004null_value_not_allowed22002null_value_no_indicator_parameter22003numeric_value_out_of_range2200Hsequence_generator_limit_exceeded22026string_data_length_mismatch22001string_data_right_truncation22011substring_error22027trim_error22024unterminated_c_string2200Fzero_length_character_string22P01floating_point_exception22P02invalid_text_representation22P03invalid_binary_representation22P04bad_copy_file_format22P05untranslatable_character2200Lnot_an_xml_document2200Minvalid_xml_document2200Ninvalid_xml_content2200Sinvalid_xml_comment2200Tinvalid_xml_processing_instruction22030duplicate_json_object_key_value22031invalid_argument_for_sql_json_datetime_function22032invalid_json_text22033invalid_sql_json_subscript22034more_than_one_sql_json_item22035no_sql_json_item22036non_numeric_sql_json_item22037non_unique_keys_in_a_json_object22038singleton_sql_json_item_required22039sql_json_array_not_found2203Asql_json_member_not_found2203Bsql_json_number_not_found2203Csql_json_object_not_found2203Dtoo_many_json_array_elements2203Etoo_many_json_object_members2203Fsql_json_scalar_required2203Gsql_json_item_cannot_be_cast_to_target_type23000integrity_constraint_violation23001restrict_violation23502not_null_violation23503foreign_key_violation23505unique_violation23514check_violation23P01exclusion_violation24000invalid_cursor_state25000invalid_transaction_state25001active_sql_transaction25002branch_transaction_already_active25008held_cursor_requires_same_isolation_level25003inappropriate_access_mode_for_branch_transaction25004inappropriate_isolation_level_for_branch_transaction25005no_active_sql_transaction_for_branch_transaction25006read_only_sql_transaction25007schema_and_data_statement_mixing_not_supported25P01no_active_sql_transaction25P02in_failed_sql_transaction25P03idle_in_transaction_session_timeout26000invalid_sql_statement_name27000triggered_data_change_violation28000invalid_authorization_specification28P01invalid_password2B000dependent_privilege_descriptors_still_exist2BP01dependent_objects_still_exist2D000invalid_transaction_termination2F000sql_routine_exception2F005function_executed_no_return_statement2F002modifying_sql_data_not_permitted2F003prohibited_sql_statement_attempted2F004reading_sql_data_not_permitted34000invalid_cursor_name38000external_routine_exception38001containing_sql_not_permitted38002modifying_sql_data_not_permitted38003prohibited_sql_statement_attempted38004reading_sql_data_not_permitted39000external_routine_invocation_exception39001invalid_sqlstate_returned39004null_value_not_allowed39P01trigger_protocol_violated39P02srf_protocol_violated39P03event_trigger_protocol_violated3B000savepoint_exception3B001invalid_savepoint_specification3D000invalid_catalog_name3F000invalid_schema_name40000transaction_rollback40002transaction_integrity_constraint_violation40001serialization_failure40003statement_completion_unknown40P01deadlock_detected42000syntax_error_or_access_rule_violation42601syntax_error42501insufficient_privilege42846cannot_coerce42803grouping_error42P20windowing_error42P19invalid_recursion42830invalid_foreign_key42602invalid_name42622name_too_long42939reserved_name42804datatype_mismatch42P18indeterminate_datatype42P21collation_mismatch42P22indeterminate_collation42809wrong_object_type428C9generated_always42703undefined_column42883undefined_function42P01undefined_table42P02undefined_parameter42704undefined_object42701duplicate_column42P03duplicate_cursor42P04duplicate_database42723duplicate_function42P05duplicate_prepared_statement42P06duplicate_schema42P07duplicate_table42712duplicate_alias42710duplicate_object42702ambiguous_column42725ambiguous_function42P08ambiguous_parameter42P09ambiguous_alias42P10invalid_column_reference42611invalid_column_definition42P11invalid_cursor_definition42P12invalid_database_definition42P13invalid_function_definition42P14invalid_prepared_statement_definition42P15invalid_schema_definition42P16invalid_table_definition42P17invalid_object_definition44000with_check_option_violation53000insufficient_resources53100disk_full53200out_of_memory53300too_many_connections53400configuration_limit_exceeded54000program_limit_exceeded54001statement_too_complex54011too_many_columns54023too_many_arguments55000object_not_in_prerequisite_state55006object_in_use55P02cant_change_runtime_param55P03lock_not_available55P04unsafe_new_enum_value_usage57000operator_intervention57014query_canceled57P01admin_shutdown57P02crash_shutdown57P03cannot_connect_now57P04database_dropped57P05idle_session_timeout58000system_error58030io_error58P01undefined_file58P02duplicate_file72000snapshot_too_oldF0000config_file_errorF0001lock_file_existsHV000fdw_errorHV005fdw_column_name_not_foundHV002fdw_dynamic_parameter_value_neededHV010fdw_function_sequence_errorHV021fdw_inconsistent_descriptor_informationHV024fdw_invalid_attribute_valueHV007fdw_invalid_column_nameHV008fdw_invalid_column_numberHV004fdw_invalid_data_typeHV006fdw_invalid_data_type_descriptorsHV091fdw_invalid_descriptor_field_identifierHV00Bfdw_invalid_handleHV00Cfdw_invalid_option_indexHV00Dfdw_invalid_option_nameHV090fdw_invalid_string_length_or_buffer_lengthHV00Afdw_invalid_string_formatHV009fdw_invalid_use_of_null_pointerHV014fdw_too_many_handlesHV001fdw_out_of_memoryHV00Pfdw_no_schemasHV00Jfdw_option_name_not_foundHV00Kfdw_reply_handleHV00Qfdw_schema_not_foundHV00Rfdw_table_not_foundHV00Lfdw_unable_to_create_executionHV00Mfdw_unable_to_create_replyHV00Nfdw_unable_to_establish_connectionP0000plpgsql_errorP0001raise_exceptionP0002no_data_foundP0003too_many_rowsP0004assert_failureXX000internal_errorXX001data_corruptedXX002index_corrupted00000successful_completion01000warning0100Cdynamic_result_sets_returned01008implicit_zero_bit_padding01003null_value_eliminated_in_set_function01007privilege_not_granted01006privilege_not_revoked01004string_data_right_truncation01P01deprecated_feature02000no_data02001no_additional_dynamic_result_sets_returned03000sql_statement_not_yet_complete08000connection_exception08003connection_does_not_exist08006connection_failure08001sqlclient_unable_to_establish_sqlconnection08004sqlserver_rejected_establishment_of_sqlconnection08007transaction_resolution_unknown08P01protocol_violation09000triggered_action_exception0A000feature_not_supported0B000invalid_transaction_initiation0F000locator_exception0F001invalid_locator_specification0L000invalid_grantor0LP01invalid_grant_operation0P000invalid_role_specification0Z000diagnostics_exception0Z002stacked_diagnostics_accessed_without_active_handler20000case_not_found21000cardinality_violation22000data_exception2202Earray_subscript_error22021character_not_in_repertoire22008datetime_field_overflow22012division_by_zero22005error_in_assignment2200Bescape_character_conflict22022indicator_overflow22015interval_field_overflow2201Einvalid_argument_for_logarithm22014invalid_argument_for_ntile_function22016invalid_argument_for_nth_value_function2201Finvalid_argument_for_power_function2201Ginvalid_argument_for_width_bucket_function22018invalid_character_value_for_cast22007invalid_datetime_format22019invalid_escape_character2200Dinvalid_escape_octet22025invalid_escape_sequence22P06nonstandard_use_of_escape_character22010invalid_indicator_parameter_value22023invalid_parameter_value22013invalid_preceding_or_following_size2201Binvalid_regular_expression2201Winvalid_row_count_in_limit_clause2201Xinvalid_row_count_in_result_offset_clause2202Hinvalid_tablesample_argument2202Ginvalid_tablesample_repeat22009invalid_time_zone_displacement_value2200Cinvalid_use_of_escape_character2200Gmost_specific_type_mismatch22004null_value_not_allowed22002null_value_no_indicator_parameter22003numeric_value_out_of_range2200Hsequence_generator_limit_exceeded22026string_data_length_mismatch22001string_data_right_truncation22011substring_error22027trim_error22024unterminated_c_string2200Fzero_length_character_string22P01floating_point_exception22P02invalid_text_representation22P03invalid_binary_representation22P04bad_copy_file_format22P05untranslatable_character2200Lnot_an_xml_document2200Minvalid_xml_document2200Ninvalid_xml_content2200Sinvalid_xml_comment2200Tinvalid_xml_processing_instruction22030duplicate_json_object_key_value22031invalid_argument_for_sql_json_datetime_function22032invalid_json_text22033invalid_sql_json_subscript22034more_than_one_sql_json_item22035no_sql_json_item22036non_numeric_sql_json_item22037non_unique_keys_in_a_json_object22038singleton_sql_json_item_required22039sql_json_array_not_found2203Asql_json_member_not_found2203Bsql_json_number_not_found2203Csql_json_object_not_found2203Dtoo_many_json_array_elements2203Etoo_many_json_object_members2203Fsql_json_scalar_required2203Gsql_json_item_cannot_be_cast_to_target_type23000integrity_constraint_violation23001restrict_violation23502not_null_violation23503foreign_key_violation23505unique_violation23514check_violation23P01exclusion_violation24000invalid_cursor_state25000invalid_transaction_state25001active_sql_transaction25002branch_transaction_already_active25008held_cursor_requires_same_isolation_level25003inappropriate_access_mode_for_branch_transaction25004inappropriate_isolation_level_for_branch_transaction25005no_active_sql_transaction_for_branch_transaction25006read_only_sql_transaction25007schema_and_data_statement_mixing_not_supported25P01no_active_sql_transaction25P02in_failed_sql_transaction25P03idle_in_transaction_session_timeout26000invalid_sql_statement_name27000triggered_data_change_violation28000invalid_authorization_specification28P01invalid_password2B000dependent_privilege_descriptors_still_exist2BP01dependent_objects_still_exist2D000invalid_transaction_termination2F000sql_routine_exception2F005function_executed_no_return_statement2F002modifying_sql_data_not_permitted2F003prohibited_sql_statement_attempted2F004reading_sql_data_not_permitted34000invalid_cursor_name38000external_routine_exception38001containing_sql_not_permitted38002modifying_sql_data_not_permitted38003prohibited_sql_statement_attempted38004reading_sql_data_not_permitted39000external_routine_invocation_exception39001invalid_sqlstate_returned39004null_value_not_allowed39P01trigger_protocol_violated39P02srf_protocol_violated39P03event_trigger_protocol_violated3B000savepoint_exception3B001invalid_savepoint_specification3D000invalid_catalog_name3F000invalid_schema_name40000transaction_rollback40002transaction_integrity_constraint_violation40001serialization_failure40003statement_completion_unknown40P01deadlock_detected42000syntax_error_or_access_rule_violation42601syntax_error42501insufficient_privilege42846cannot_coerce42803grouping_error42P20windowing_error42P19invalid_recursion42830invalid_foreign_key42602invalid_name42622name_too_long42939reserved_name42804datatype_mismatch42P18indeterminate_datatype42P21collation_mismatch42P22indeterminate_collation42809wrong_object_type428C9generated_always42703undefined_column42883undefined_function42P01undefined_table42P02undefined_parameter42704undefined_object42701duplicate_column42P03duplicate_cursor42P04duplicate_database42723duplicate_function42P05duplicate_prepared_statement42P06duplicate_schema42P07duplicate_table42712duplicate_alias42710duplicate_object42702ambiguous_column42725ambiguous_function42P08ambiguous_parameter42P09ambiguous_alias42P10invalid_column_reference42611invalid_column_definition42P11invalid_cursor_definition42P12invalid_database_definition42P13invalid_function_definition42P14invalid_prepared_statement_definition42P15invalid_schema_definition42P16invalid_table_definition42P17invalid_object_definition44000with_check_option_violation53000insufficient_resources53100disk_full53200out_of_memory53300too_many_connections53400configuration_limit_exceeded54000program_limit_exceeded54001statement_too_complex54011too_many_columns54023too_many_arguments55000object_not_in_prerequisite_state55006object_in_use55P02cant_change_runtime_param55P03lock_not_available55P04unsafe_new_enum_value_usage57000operator_intervention57014query_canceled57P01admin_shutdown57P02crash_shutdown57P03cannot_connect_now57P04database_dropped57P05idle_session_timeout58000system_error58030io_error58P01undefined_file58P02duplicate_file72000snapshot_too_oldF0000config_file_errorF0001lock_file_existsHV000fdw_errorHV005fdw_column_name_not_foundHV002fdw_dynamic_parameter_value_neededHV010fdw_function_sequence_errorHV021fdw_inconsistent_descriptor_informationHV024fdw_invalid_attribute_valueHV007fdw_invalid_column_nameHV008fdw_invalid_column_numberHV004fdw_invalid_data_typeHV006fdw_invalid_data_type_descriptorsHV091fdw_invalid_descriptor_field_identifierHV00Bfdw_invalid_handleHV00Cfdw_invalid_option_indexHV00Dfdw_invalid_option_nameHV090fdw_invalid_string_length_or_buffer_lengthHV00Afdw_invalid_string_formatHV009fdw_invalid_use_of_null_pointerHV014fdw_too_many_handlesHV001fdw_out_of_memoryHV00Pfdw_no_schemasHV00Jfdw_option_name_not_foundHV00Kfdw_reply_handleHV00Qfdw_schema_not_foundHV00Rfdw_table_not_foundHV00Lfdw_unable_to_create_executionHV00Mfdw_unable_to_create_replyHV00Nfdw_unable_to_establish_connectionP0000plpgsql_errorP0001raise_exceptionP0002no_data_foundP0003too_many_rowsP0004assert_failureXX000internal_errorXX001data_corruptedXX002index_corrupted