Обсуждение: Support for sslverify

Поиск
Список
Период
Сортировка

Support for sslverify

От
Magnus Hagander
Дата:
We've seen it here and Dave reported to me on IM that he has received
further reports of people getting stuck by the new 8.4 SSL code that
verifies server certificates by default.

I think this will happen for example for everybody who has their pg on a
debian server and their client elsewhere, for example, since debian
enables a snakeoil SSL cert by default (which in itself is a pretty bad
idea, but it's what they do)


Should we provide an option to override this (connection option
sslverify) in the connection dialog? And is it something we need to do
for this version (yes, I know it's already in beta..)

//Magnus

Re: Support for sslverify

От
Dave Page
Дата:
On Sun, Mar 15, 2009 at 2:51 PM, Magnus Hagander <magnus@hagander.net> wrote:
> We've seen it here and Dave reported to me on IM that he has received
> further reports of people getting stuck by the new 8.4 SSL code that
> verifies server certificates by default.
>
> I think this will happen for example for everybody who has their pg on a
> debian server and their client elsewhere, for example, since debian
> enables a snakeoil SSL cert by default (which in itself is a pretty bad
> idea, but it's what they do)
>
>
> Should we provide an option to override this (connection option
> sslverify) in the connection dialog? And is it something we need to do
> for this version (yes, I know it's already in beta..)

There's support for this in libpq aready? If so, then please go ahead
and fix pgAdmin :-)

Note that the server connection diagloue is already pretty much at the
maximum height, so any changes there will probably need to include
splitting of the tabset.

--
Dave Page
EnterpriseDB UK:   http://www.enterprisedb.com

Re: Support for sslverify

От
Dave Page
Дата:
On Mon, Mar 16, 2009 at 8:03 AM, Magnus Hagander <magnus@hagander.net> wrote:

>> Note that the server connection diagloue is already pretty much at the
>> maximum height, so any changes there will probably need to include
>> splitting of the tabset.
>
> Crap. That something we want to do between betas?

It's only UI. I can live with it given that it's clearly going to
cause user complaints otherwise.



--
Dave Page
EnterpriseDB UK:   http://www.enterprisedb.com

Re: Support for sslverify

От
Magnus Hagander
Дата:
On 15 mar 2009, at 17.00, Dave Page <dpage@pgadmin.org> wrote:

> On Sun, Mar 15, 2009 at 2:51 PM, Magnus Hagander
> <magnus@hagander.net> wrote:
>> We've seen it here and Dave reported to me on IM that he has received
>> further reports of people getting stuck by the new 8.4 SSL code that
>> verifies server certificates by default.
>>
>> I think this will happen for example for everybody who has their pg
>> on a
>> debian server and their client elsewhere, for example, since debian
>> enables a snakeoil SSL cert by default (which in itself is a pretty
>> bad
>> idea, but it's what they do)
>>
>>
>> Should we provide an option to override this (connection option
>> sslverify) in the connection dialog? And is it something we need to
>> do
>> for this version (yes, I know it's already in beta..)
>
> There's support for this in libpq aready? If so, then please go ahead
> and fix pgAdmin :-)

Yes, that was part of the original patch. You can set to verify all
(never before, and default), verify ca (default before *if* the root
cert was there) or no verification at all.


> Note that the server connection diagloue is already pretty much at the
> maximum height, so any changes there will probably need to include
> splitting of the tabset.

Crap. That something we want to do between betas?

/Magnus


Re: Support for sslverify

От
Magnus Hagander
Дата:
Magnus Hagander wrote:
> On 15 mar 2009, at 17.00, Dave Page <dpage@pgadmin.org> wrote:
>
>> On Sun, Mar 15, 2009 at 2:51 PM, Magnus Hagander <magnus@hagander.net>
>> wrote:
>>> We've seen it here and Dave reported to me on IM that he has received
>>> further reports of people getting stuck by the new 8.4 SSL code that
>>> verifies server certificates by default.
>>>
>>> I think this will happen for example for everybody who has their pg on a
>>> debian server and their client elsewhere, for example, since debian
>>> enables a snakeoil SSL cert by default (which in itself is a pretty bad
>>> idea, but it's what they do)
>>>
>>>
>>> Should we provide an option to override this (connection option
>>> sslverify) in the connection dialog? And is it something we need to do
>>> for this version (yes, I know it's already in beta..)
>>
>> There's support for this in libpq aready? If so, then please go ahead
>> and fix pgAdmin :-)
>
> Yes, that was part of the original patch. You can set to verify all
> (never before, and default), verify ca (default before *if* the root
> cert was there) or no verification at all.
>
>
>> Note that the server connection diagloue is already pretty much at the
>> maximum height, so any changes there will probably need to include
>> splitting of the tabset.
>
> Crap. That something we want to do between betas?

OK, here's a patch that tries this. Since we're in beta, I definitely
want eyes on it before I commit :-)

//Magnus

Index: include/db/pgConn.h
===================================================================
--- include/db/pgConn.h    (revision 7708)
+++ include/db/pgConn.h    (working copy)
@@ -81,7 +81,7 @@
 class pgConn
 {
 public:
-    pgConn(const wxString& server = wxT(""), const wxString& database = wxT(""), const wxString& username = wxT(""),
constwxString& password = wxT(""), int port = 5432, int sslmode=0, OID oid=0); 
+    pgConn(const wxString& server = wxT(""), const wxString& database = wxT(""), const wxString& username = wxT(""),
constwxString& password = wxT(""), int port = 5432, int sslmode=0, int sslverify=0, OID oid=0); 
     ~pgConn();

     bool HasPrivilege(const wxString &objTyp, const wxString &objName, const wxString &priv);
@@ -117,7 +117,9 @@
     wxString GetTTY() const { return wxString(PQtty(conn), *conv); }
     wxString GetOptions() const { return wxString(PQoptions(conn), *conv); }
     int GetSslMode() const { return save_sslmode; }
+    int GetSslVerifyMode() const { return save_sslverifymode;}
     wxString GetSslModeName();
+    wxString GetSslVerifyModeName();
     int GetBackendPID() const { return PQbackendPID(conn); }
     int GetStatus() const;
     int GetLastResultStatus() const { return lastResultStatus; }
@@ -172,7 +174,7 @@
     wxString reservedNamespaces;

     wxString save_server, save_database, save_username, save_password;
-    int save_port, save_sslmode;
+    int save_port, save_sslmode, save_sslverifymode;
     OID save_oid;
 };

Index: include/utils/sysSettings.h
===================================================================
--- include/utils/sysSettings.h    (revision 7708)
+++ include/utils/sysSettings.h    (working copy)
@@ -48,6 +48,8 @@
     void SetLastPort(const int newval) { Write(wxT("LastPort"), newval); }
     int GetLastSSL() const { int i; Read(wxT("LastSSL"), &i, 0); return i; }
     void SetLastSSL(const int newval) { Write(wxT("LastSSL"), newval); }
+    int GetLastSSLverify() const { int i; Read(wxT("LastSSLverify"), &i, 0); return i; }
+    void SetLastSSLverify(const int newval) { Write(wxT("LastSSLverify"), newval); }

     // Helper paths
     wxString GetSlonyPath() const { wxString s; Read(wxT("SlonyPath"), &s, wxEmptyString); return s; }
Index: include/schema/pgServer.h
===================================================================
--- include/schema/pgServer.h    (revision 7708)
+++ include/schema/pgServer.h    (working copy)
@@ -38,7 +38,7 @@
 class pgServer : public pgObject
 {
 public:
-    pgServer(const wxString& newServer = wxT(""), const wxString& newDescription = wxT(""), const wxString&
newDatabase= wxT(""), const wxString& newUsername = wxT(""), int newPort = 5432, bool storePwd=false, bool
restore=true,int sslMode=0, const wxString &colour = wxEmptyString); 
+    pgServer(const wxString& newServer = wxT(""), const wxString& newDescription = wxT(""), const wxString&
newDatabase= wxT(""), const wxString& newUsername = wxT(""), int newPort = 5432, bool storePwd=false, bool
restore=true,int sslMode=0, int sslVerifyMode=0, const wxString &colour = wxEmptyString); 
     ~pgServer();
     int GetIconId();

@@ -99,10 +99,12 @@
     wxString GetFullIdentifier();
     int GetPort() const { return port; }
     int GetSSL() const { return ssl; }
+    int GetSSLverify() const { return sslverify; }
     bool GetConnected() const { return connected; }
     void iSetDatabase(const wxString& newVal) { database = newVal; }
     void iSetPort(int newval) { port=newval; }
     void iSetSSL(int newval) { ssl=newval; }
+    void iSetSSLverify(int newval) { sslverify=newval; }
     void iSetUsername(const wxString& newVal) { username = newVal; }
     void iSetPassword(const wxString& newVal) { password = newVal; }
     void iSetStorePwd(const bool b) { storePwd = b; }
@@ -146,7 +148,7 @@
     wxString database, username, password, ver, error;
     wxString lastDatabase, lastSchema, description, serviceId, discoveryId;
     wxDateTime upSince;
-    int port, ssl;
+    int port, ssl, sslverify;
     bool storePwd, restore, discovered, createPrivilege, superUser, createRole;
     OID lastSystemOID;
     OID dbOid;
Index: frm/frmMain.cpp
===================================================================
--- frm/frmMain.cpp    (revision 7708)
+++ frm/frmMain.cpp    (working copy)
@@ -1049,6 +1049,7 @@
             settings->Write(key + wxT("DbRestriction"), server->GetDbRestriction());
             settings->Write(key + wxT("Colour"), server->GetColour());
             settings->Write(key + wxT("SSL"), server->GetSSL());
+            settings->Write(key + wxT("SSLverify"), server->GetSSLverify());

             pgCollection *coll=browser->FindCollection(databaseFactory, server->GetId());
             if (coll)
Index: db/pgConn.cpp
===================================================================
--- db/pgConn.cpp    (revision 7708)
+++ db/pgConn.cpp    (working copy)
@@ -48,7 +48,7 @@
     ((pgConn*)arg)->Notice(message);
 }

-pgConn::pgConn(const wxString& server, const wxString& database, const wxString& username, const wxString& password,
intport, int sslmode, OID oid) 
+pgConn::pgConn(const wxString& server, const wxString& database, const wxString& username, const wxString& password,
intport, int sslmode, int sslverifymode, OID oid) 
 {
     wxString msg, hostip, hostname;

@@ -58,6 +58,7 @@
     save_password = password;
     save_port = port;
     save_sslmode = sslmode;
+    save_sslverifymode = sslverifymode;
     save_oid = oid;

     memset(features, 0, sizeof(features));
@@ -160,6 +161,15 @@
             case 2: connstr.Append(wxT(" requiressl=0"));   break;
         }
     }
+    if (libpqVersion >= 8.4)
+    {
+        switch (sslverifymode)
+        {
+            case 1: connstr.Append(wxT(" sslverify=cn"));   break;
+            case 2: connstr.Append(wxT(" sslverify=cert")); break;
+            case 3: connstr.Append(wxT(" sslverify=none")); break;
+        }
+    }
     connstr.Trim(false);

     // Open the connection
@@ -252,7 +262,7 @@

 pgConn *pgConn::Duplicate()
 {
-    return new pgConn(wxString(save_server), wxString(save_database), wxString(save_username),
wxString(save_password),save_port, save_sslmode, save_oid); 
+    return new pgConn(wxString(save_server), wxString(save_database), wxString(save_username),
wxString(save_password),save_port, save_sslmode, save_sslverifymode, save_oid); 
 }

 // Return the SSL mode name
@@ -262,22 +272,33 @@
     {
         case 1:
             return wxT("require");
-            break;
         case 2:
             return wxT("prefer");
-            break;
         case 3:
             return wxT("allow");
-            break;
         case 4:
             return wxT("disable");
-            break;
         default:
             return wxT("prefer");
-            break;
     }
 }

+// Return the SSL verify mode name
+wxString pgConn::GetSslVerifyModeName()
+{
+    switch (save_sslverifymode)
+    {
+        case 1:
+            return wxT("cn");
+        case 2:
+            return wxT("cert");
+        case 3:
+            return wxT("none");
+        default:
+            return wxT("cn");
+    }
+}
+
 bool pgConn::GetIsEdb()
 {
     // to retrieve edb flag
@@ -481,9 +502,14 @@
         {
             if (!strcmp(co->keyword, "sslmode"))
             {
-                libpqVersion=7.4;
-                break;
+                if (libpqVersion < 7.4)
+                    libpqVersion=7.4;
             }
+            if (!strcmp(co->keyword, "sslverify"))
+            {
+                if (libpqVersion < 8.4)
+                    libpqVersion=8.4;
+            }
             co++;
         }
         PQconninfoFree(cio);
Index: schema/pgServer.cpp
===================================================================
--- schema/pgServer.cpp    (revision 7708)
+++ schema/pgServer.cpp    (working copy)
@@ -39,7 +39,7 @@

 #define DEFAULT_PG_DATABASE wxT("postgres")

-pgServer::pgServer(const wxString& newName, const wxString& newDescription, const wxString& newDatabase, const
wxString&newUsername, int newPort, bool _storePwd, bool _restore, int _ssl, const wxString &_colour) 
+pgServer::pgServer(const wxString& newName, const wxString& newDescription, const wxString& newDatabase, const
wxString&newUsername, int newPort, bool _storePwd, bool _restore, int _ssl, int _sslverify, const wxString &_colour) 
 : pgObject(serverFactory, newName)
 {
     description = newDescription;
@@ -47,6 +47,7 @@
     username = newUsername;
     port = newPort;
     ssl=_ssl;
+    sslverify=_sslverify;
     colour = _colour;
     serverIndex=0;

@@ -137,7 +138,7 @@
         dbName = GetDatabaseName();
         oid = dbOid;
     }
-    pgConn *conn=new pgConn(GetName(), dbName, username, password, port, ssl, oid);
+    pgConn *conn=new pgConn(GetName(), dbName, username, password, port, ssl, sslverify, oid);

     if (conn && conn->GetStatus() != PGCONN_OK)
     {
@@ -614,21 +615,21 @@

         if (database.IsEmpty())
         {
-            conn = new pgConn(GetName(), DEFAULT_PG_DATABASE, username, password, port, ssl);
+            conn = new pgConn(GetName(), DEFAULT_PG_DATABASE, username, password, port, ssl, sslverify);
             if (conn->GetStatus() == PGCONN_OK)
                 database=DEFAULT_PG_DATABASE;
             else if (conn->GetStatus() == PGCONN_BAD && conn->GetLastError().Find(
                                 wxT("database \"") DEFAULT_PG_DATABASE wxT("\" does not exist")) >= 0)
             {
                 delete conn;
-                conn = new pgConn(GetName(), wxT("template1"), username, password, port, ssl);
+                conn = new pgConn(GetName(), wxT("template1"), username, password, port, ssl, sslverify);
                 if (conn && conn->GetStatus() == PGCONN_OK)
                     database=wxT("template1");
             }
         }
         else
         {
-            conn = new pgConn(GetName(), database, username, password, port, ssl);
+            conn = new pgConn(GetName(), database, username, password, port, ssl, sslverify);
             if (!conn)
             {
                 form->EndMsg(false);
@@ -933,6 +934,17 @@
                     }
                     properties->AppendItem(_("SSL Mode"), sslMode);
                 }
+                if (sslverify > 0)
+                {
+                    wxString sslVerifyMode;
+                    switch (sslverify)
+                    {
+                        case 1: sslVerifyMode = _("Full verification"); break;
+                        case 2: sslVerifyMode = _("Certificate only"); break;
+                        case 3: sslVerifyMode = _("No verification"); break;
+                    }
+                    properties->AppendItem(_("SSL Verify Mode"), sslVerifyMode);
+                }
             }
 #endif
         }
@@ -1079,7 +1091,7 @@
 {
     long numServers=settings->Read(wxT("Servers/Count"), 0L);

-    long loop, port, ssl=0;
+    long loop, port, ssl=0, sslverify=0;
     wxString key, servername, description, database, username, lastDatabase, lastSchema, storePwd, restore, serviceID,
discoveryID,dbRestriction, colour; 
     pgServer *server=0;

@@ -1118,10 +1130,11 @@
         // SSL mode
 #ifdef SSL
         settings->Read(key + wxT("SSL"), &ssl, 0);
+        settings->Read(key + wxT("SSLverify"), &sslverify, 0);
 #endif

         // Add the Server node
-        server = new pgServer(servername, description, database, username, port, StrToBool(storePwd),
StrToBool(restore),ssl); 
+        server = new pgServer(servername, description, database, username, port, StrToBool(storePwd),
StrToBool(restore),ssl, sslverify); 
         server->iSetLastDatabase(lastDatabase);
         server->iSetLastSchema(lastSchema);
         server->iSetServiceID(serviceID);
Index: dlg/dlgServer.cpp
===================================================================
--- dlg/dlgServer.cpp    (revision 7708)
+++ dlg/dlgServer.cpp    (working copy)
@@ -29,6 +29,7 @@
 #define cbDatabase      CTRL_COMBOBOX("cbDatabase")
 #define txtPort         CTRL_TEXT("txtPort")
 #define cbSSL           CTRL_COMBOBOX("cbSSL")
+#define cbSSLverify     CTRL_COMBOBOX("cbSSLverify")
 #define txtUsername     CTRL_TEXT("txtUsername")
 #define stTryConnect    CTRL_STATIC("stTryConnect")
 #define chkTryConnect   CTRL_CHECKBOX("chkTryConnect")
@@ -53,6 +54,7 @@
     EVT_TEXT(XRCID("txtUsername"),                  dlgProperty::OnChange)
     EVT_TEXT(XRCID("txtDbRestriction"),             dlgServer::OnChangeRestr)
     EVT_COMBOBOX(XRCID("cbSSL"),                    dlgProperty::OnChange)
+    EVT_COMBOBOX(XRCID("cbSSLverify"),              dlgProperty::OnChange)
     EVT_CHECKBOX(XRCID("chkStorePwd"),              dlgProperty::OnChange)
     EVT_CHECKBOX(XRCID("chkRestore"),               dlgProperty::OnChange)
     EVT_CHECKBOX(XRCID("chkTryConnect"),            dlgServer::OnChangeTryConnect)
@@ -85,6 +87,8 @@
     txtPort->SetValue(NumToStr((long)settings->GetLastPort()));
     if (!cbSSL->IsEmpty())
         cbSSL->SetSelection(settings->GetLastSSL());
+    if (!cbSSLverify->IsEmpty())
+        cbSSLverify->SetSelection(settings->GetLastSSLverify());
     txtUsername->SetValue(settings->GetLastUsername());

     chkTryConnect->SetValue(true);
@@ -105,6 +109,7 @@
         settings->SetLastDatabase(cbDatabase->GetValue());
         settings->SetLastPort(StrToLong(txtPort->GetValue()));
         settings->SetLastSSL(cbSSL->GetCurrentSelection());
+        settings->SetLastSSLverify(cbSSLverify->GetCurrentSelection());
         settings->SetLastUsername(txtUsername->GetValue());
     }
 }
@@ -142,6 +147,7 @@
         }
         server->iSetPort(StrToLong(txtPort->GetValue()));
         server->iSetSSL(cbSSL->GetCurrentSelection());
+        server->iSetSSLverify(cbSSLverify->GetCurrentSelection());
         server->iSetDatabase(cbDatabase->GetValue());
         server->iSetUsername(txtUsername->GetValue());
         server->iSetStorePwd(chkStorePwd->GetValue());
@@ -215,6 +221,7 @@
 int dlgServer::Go(bool modal)
 {
     cbSSL->Append(wxT(" "));
+    cbSSLverify->Append(wxT(" "));

 #ifdef SSL
     cbSSL->Append(_("require"));
@@ -225,6 +232,13 @@
         cbSSL->Append(_("allow"));
         cbSSL->Append(_("disable"));
     }
+
+    if (pgConn::GetLibpqVersion() >= 8.4)
+    {
+        cbSSLverify->Append(_("Full verification"));
+        cbSSLverify->Append(_("Certificate only"));
+        cbSSLverify->Append(_("No verification"));
+    }
 #endif

     if (server)
@@ -235,6 +249,7 @@
         txtService->SetValue(server->GetServiceID());
         txtPort->SetValue(NumToStr((long)server->GetPort()));
         cbSSL->SetSelection(server->GetSSL());
+        cbSSLverify->SetSelection(server->GetSSLverify());
         cbDatabase->SetValue(server->GetDatabaseName());
         txtUsername->SetValue(server->GetUsername());
         chkStorePwd->SetValue(server->GetStorePwd());
@@ -250,6 +265,7 @@
             cbDatabase->Disable();
             txtPort->Disable();
             cbSSL->Disable();
+            cbSSLverify->Disable();
             txtUsername->Disable();
             chkStorePwd->Disable();
         }
@@ -282,7 +298,8 @@
     pgObject *obj=new pgServer(GetName(), txtDescription->GetValue(), cbDatabase->GetValue(),
         txtUsername->GetValue(), StrToLong(txtPort->GetValue()),
         chkTryConnect->GetValue() && chkStorePwd->GetValue(),
-        chkRestore->GetValue(), cbSSL->GetCurrentSelection(), txtColour->GetValue());
+        chkRestore->GetValue(), cbSSL->GetCurrentSelection(),
+        cbSSLverify->GetCurrentSelection(), txtColour->GetValue());

     return obj;
 }
@@ -320,6 +337,7 @@
                || cbDatabase->GetValue() != server->GetDatabaseName()
                || txtUsername->GetValue() != server->GetUsername()
                || cbSSL->GetCurrentSelection() != server->GetSSL()
+               || cbSSLverify->GetCurrentSelection() != server->GetSSLverify()
                || chkStorePwd->GetValue() != server->GetStorePwd()
                || chkRestore->GetValue() != server->GetRestore()
                || txtDbRestriction->GetValue() != server->GetDbRestriction()
@@ -332,6 +350,7 @@
 #else
     bool isPipe = (name.IsEmpty() || name.StartsWith(wxT("/")));
     cbSSL->Enable(!isPipe);
+    cbSSLverify->Enable(!isPipe);
 #endif
     CheckValid(enable, !txtDescription->GetValue().IsEmpty(), _("Please specify description."));
     CheckValid(enable, StrToLong(txtPort->GetValue()) > 0, _("Please specify port."));
Index: ui/dlgServer.xrc
===================================================================
--- ui/dlgServer.xrc    (revision 7708)
+++ ui/dlgServer.xrc    (working copy)
@@ -66,12 +66,28 @@
                   <border>4</border>
                 </object>
                 <object class="sizeritem">
-                  <object class="wxComboBox" name="cbSSL">
+                 <object class="wxGridSizer">
+                  <cols>2</cols>
+                  <rows>2</rows>
+                  <growablecols>1</growablecols>
+                  <object class="sizeritem">
+                   <object class="wxComboBox" name="cbSSL">
                     <style>wxCB_READONLY|wxCB_DROPDOWN</style>
                     <content/>
+                   </object>
+                   <flag>wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag>
+                   <border>4</border>
                   </object>
-                  <flag>wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag>
-                  <border>4</border>
+                  <object class="sizeritem">
+                   <object class="wxComboBox" name="cbSSLverify">
+                    <style>wxCB_READONLY|wxCB_DROPDOWN</style>
+                    <content/>
+                   </object>
+                   <flag>wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag>
+                   <border>4</border>
+                  </object>
+                 </object>
+                 <flag>wxGROW</flag>
                 </object>
                 <object class="sizeritem">
                   <object class="wxStaticText" name="stDatabase">
@@ -258,4 +274,4 @@
       </object>
     </object>
   </object>
-</resource>
\ No newline at end of file
+</resource>

Re: Support for sslverify

От
Dave Page
Дата:
On Mon, Mar 16, 2009 at 1:57 PM, Magnus Hagander <magnus@hagander.net> wrote:

> OK, here's a patch that tries this. Since we're in beta, I definitely
> want eyes on it before I commit :-)

OK, I've applied eyes - here are my immediate thoughts:

- The verify mode strings look quite long, per my comment on IM.
Perhaps Full, Certificate or None would be better.

- There doesn't seem to be any way to push the verify mode down to the
backup/backupall/backupglobals/restore dialogues, or to the debugger
(which, annoyingly, still has it's own connection class). Do we want
to re-verify in those places, or just set verify=none, as we've
already verified at initial connection? I guess in theory a mitm
attack could start after we initially connect.

- Should verify mode also be exposed in the plugins interface? SSL
mode is, so it would seem logical.

--
Dave Page
EnterpriseDB UK:   http://www.enterprisedb.com

Re: Support for sslverify

От
Magnus Hagander
Дата:
Dave Page wrote:
> On Mon, Mar 16, 2009 at 1:57 PM, Magnus Hagander <magnus@hagander.net> wrote:
>
>> OK, here's a patch that tries this. Since we're in beta, I definitely
>> want eyes on it before I commit :-)
>
> OK, I've applied eyes - here are my immediate thoughts:
>
> - The verify mode strings look quite long, per my comment on IM.
> Perhaps Full, Certificate or None would be better.

I considered that, but I think that would be rather confusing the way
the dialog is done. Then we'd need a separate header for it, no?

FWIW, they fit fine in the dropdown on my Ubuntu box...

The way it is now, only the "verification" part will slip outside the
dialog box it they're too long, so I don't think it's too bad?



> - There doesn't seem to be any way to push the verify mode down to the
> backup/backupall/backupglobals/restore dialogues, or to the debugger
> (which, annoyingly, still has it's own connection class). Do we want
> to re-verify in those places, or just set verify=none, as we've
> already verified at initial connection? I guess in theory a mitm
> attack could start after we initially connect.

Ick. I'll need to look into that. We must absolutely verify every
connection, anything else is very stupid.


> - Should verify mode also be exposed in the plugins interface? SSL
> mode is, so it would seem logical.

Yes, if it is, it should be. I think I need to go over my grepping a bit
more carefully to see if there are more places.

//Magnus


Re: Support for sslverify

От
Dave Page
Дата:
On Mon, Mar 16, 2009 at 2:35 PM, Magnus Hagander <magnus@hagander.net> wrote:
> Dave Page wrote:
>> On Mon, Mar 16, 2009 at 1:57 PM, Magnus Hagander <magnus@hagander.net> wrote:
>>
>>> OK, here's a patch that tries this. Since we're in beta, I definitely
>>> want eyes on it before I commit :-)
>>
>> OK, I've applied eyes - here are my immediate thoughts:
>>
>> - The verify mode strings look quite long, per my comment on IM.
>> Perhaps Full, Certificate or None would be better.
>
> I considered that, but I think that would be rather confusing the way
> the dialog is done. Then we'd need a separate header for it, no?
>
> FWIW, they fit fine in the dropdown on my Ubuntu box...
>
> The way it is now, only the "verification" part will slip outside the
> dialog box it they're too long, so I don't think it's too bad?

Meh, it was just a thought.

>
>> - There doesn't seem to be any way to push the verify mode down to the
>> backup/backupall/backupglobals/restore dialogues, or to the debugger
>> (which, annoyingly, still has it's own connection class). Do we want
>> to re-verify in those places, or just set verify=none, as we've
>> already verified at initial connection? I guess in theory a mitm
>> attack could start after we initially connect.
>
> Ick. I'll need to look into that. We must absolutely verify every
> connection, anything else is very stupid.
>
>
>> - Should verify mode also be exposed in the plugins interface? SSL
>> mode is, so it would seem logical.
>
> Yes, if it is, it should be. I think I need to go over my grepping a bit
> more carefully to see if there are more places.

:-)



--
Dave Page
EnterpriseDB UK:   http://www.enterprisedb.com

Re: Support for sslverify

От
Magnus Hagander
Дата:
Dave Page wrote:
> On Mon, Mar 16, 2009 at 2:35 PM, Magnus Hagander <magnus@hagander.net> wrote:
>> Dave Page wrote:
>>> On Mon, Mar 16, 2009 at 1:57 PM, Magnus Hagander <magnus@hagander.net> wrote:
>>> - There doesn't seem to be any way to push the verify mode down to the
>>> backup/backupall/backupglobals/restore dialogues, or to the debugger
>>> (which, annoyingly, still has it's own connection class). Do we want
>>> to re-verify in those places, or just set verify=none, as we've
>>> already verified at initial connection? I guess in theory a mitm
>>> attack could start after we initially connect.
>> Ick. I'll need to look into that. We must absolutely verify every
>> connection, anything else is very stupid.

This look better?

(I haven't actually tested the backup stuff :-P But it builds..)

I also noticed we have windows linebreaks in at least one file in the
debugger directory...

//Magnus

Index: pgadmin/include/debugger/dbgPgConn.h
===================================================================
--- pgadmin/include/debugger/dbgPgConn.h    (revision 7708)
+++ pgadmin/include/debugger/dbgPgConn.h    (working copy)
@@ -57,7 +57,8 @@
               const wxString &username = wxT( "" ),
               const wxString &password = wxT( "" ),
               const wxString &port     = wxT( "5432" ),
-              int sslmode               = 0 );
+              int sslmode               = 0,
+              int sslverify            = 0 );

     dbgPgConn( frmDebugger *frame, const dbgConnProp & props, bool startThread = true );

@@ -83,7 +84,7 @@

   private:

-    void Init( const wxString &server, const wxString &database, const wxString &userName, const wxString &password,
constwxString &port, int sslmode, bool startThread ); 
+    void Init( const wxString &server, const wxString &database, const wxString &userName, const wxString &password,
constwxString &port, int sslmode, int sslverify, bool startThread ); 

     PGconn *m_pgConn;               // libpq connection handler
     dbgPgThread *m_workerThread;    // Worker thread (this thread interacts with the server)
Index: pgadmin/include/debugger/dbgConnProp.h
===================================================================
--- pgadmin/include/debugger/dbgConnProp.h    (revision 7708)
+++ pgadmin/include/debugger/dbgConnProp.h    (working copy)
@@ -32,6 +32,7 @@
     wxString    m_port;            // Port number
     wxString    m_debugPort;    // Port number for debugger connection
     int            m_sslMode;        // SSL Mode
+    int             m_sslVerify;            // SSL Certificate Verify Mode
 };

 #endif
Index: pgadmin/include/db/pgConn.h
===================================================================
--- pgadmin/include/db/pgConn.h    (revision 7708)
+++ pgadmin/include/db/pgConn.h    (working copy)
@@ -81,7 +81,7 @@
 class pgConn
 {
 public:
-    pgConn(const wxString& server = wxT(""), const wxString& database = wxT(""), const wxString& username = wxT(""),
constwxString& password = wxT(""), int port = 5432, int sslmode=0, OID oid=0); 
+    pgConn(const wxString& server = wxT(""), const wxString& database = wxT(""), const wxString& username = wxT(""),
constwxString& password = wxT(""), int port = 5432, int sslmode=0, int sslverify=0, OID oid=0); 
     ~pgConn();

     bool HasPrivilege(const wxString &objTyp, const wxString &objName, const wxString &priv);
@@ -117,7 +117,9 @@
     wxString GetTTY() const { return wxString(PQtty(conn), *conv); }
     wxString GetOptions() const { return wxString(PQoptions(conn), *conv); }
     int GetSslMode() const { return save_sslmode; }
+    int GetSslVerifyMode() const { return save_sslverifymode;}
     wxString GetSslModeName();
+    wxString GetSslVerifyModeName();
     int GetBackendPID() const { return PQbackendPID(conn); }
     int GetStatus() const;
     int GetLastResultStatus() const { return lastResultStatus; }
@@ -172,7 +174,7 @@
     wxString reservedNamespaces;

     wxString save_server, save_database, save_username, save_password;
-    int save_port, save_sslmode;
+    int save_port, save_sslmode, save_sslverifymode;
     OID save_oid;
 };

Index: pgadmin/include/utils/sysSettings.h
===================================================================
--- pgadmin/include/utils/sysSettings.h    (revision 7708)
+++ pgadmin/include/utils/sysSettings.h    (working copy)
@@ -48,6 +48,8 @@
     void SetLastPort(const int newval) { Write(wxT("LastPort"), newval); }
     int GetLastSSL() const { int i; Read(wxT("LastSSL"), &i, 0); return i; }
     void SetLastSSL(const int newval) { Write(wxT("LastSSL"), newval); }
+    int GetLastSSLverify() const { int i; Read(wxT("LastSSLverify"), &i, 0); return i; }
+    void SetLastSSLverify(const int newval) { Write(wxT("LastSSLverify"), newval); }

     // Helper paths
     wxString GetSlonyPath() const { wxString s; Read(wxT("SlonyPath"), &s, wxEmptyString); return s; }
Index: pgadmin/include/schema/pgServer.h
===================================================================
--- pgadmin/include/schema/pgServer.h    (revision 7708)
+++ pgadmin/include/schema/pgServer.h    (working copy)
@@ -38,7 +38,7 @@
 class pgServer : public pgObject
 {
 public:
-    pgServer(const wxString& newServer = wxT(""), const wxString& newDescription = wxT(""), const wxString&
newDatabase= wxT(""), const wxString& newUsername = wxT(""), int newPort = 5432, bool storePwd=false, bool
restore=true,int sslMode=0, const wxString &colour = wxEmptyString); 
+    pgServer(const wxString& newServer = wxT(""), const wxString& newDescription = wxT(""), const wxString&
newDatabase= wxT(""), const wxString& newUsername = wxT(""), int newPort = 5432, bool storePwd=false, bool
restore=true,int sslMode=0, int sslVerifyMode=0, const wxString &colour = wxEmptyString); 
     ~pgServer();
     int GetIconId();

@@ -99,10 +99,12 @@
     wxString GetFullIdentifier();
     int GetPort() const { return port; }
     int GetSSL() const { return ssl; }
+    int GetSSLverify() const { return sslverify; }
     bool GetConnected() const { return connected; }
     void iSetDatabase(const wxString& newVal) { database = newVal; }
     void iSetPort(int newval) { port=newval; }
     void iSetSSL(int newval) { ssl=newval; }
+    void iSetSSLverify(int newval) { sslverify=newval; }
     void iSetUsername(const wxString& newVal) { username = newVal; }
     void iSetPassword(const wxString& newVal) { password = newVal; }
     void iSetStorePwd(const bool b) { storePwd = b; }
@@ -146,7 +148,7 @@
     wxString database, username, password, ver, error;
     wxString lastDatabase, lastSchema, description, serviceId, discoveryId;
     wxDateTime upSince;
-    int port, ssl;
+    int port, ssl, sslverify;
     bool storePwd, restore, discovered, createPrivilege, superUser, createRole;
     OID lastSystemOID;
     OID dbOid;
Index: pgadmin/include/dlg/dlgSelectConnection.h
===================================================================
--- pgadmin/include/dlg/dlgSelectConnection.h    (revision 7708)
+++ pgadmin/include/dlg/dlgSelectConnection.h    (working copy)
@@ -24,7 +24,7 @@
     wxString GetHelpPage() const;
     pgServer *GetServer() { return remoteServer; }
     pgConn *CreateConn();
-    pgConn *CreateConn(wxString& server, wxString& dbname, wxString& username, int port, int sslmode, bool writeMRU =
false);
+    pgConn *CreateConn(wxString& server, wxString& dbname, wxString& username, int port, int sslmode, int sslveirfy,
boolwriteMRU = false);
 
     wxString GetServerName();
     wxString GetDatabase();
 
Index: pgadmin/pgAdmin3.cpp
===================================================================
--- pgadmin/pgAdmin3.cpp    (revision 7708)
+++ pgadmin/pgAdmin3.cpp    (working copy)
@@ -451,7 +451,7 @@
             {
                 wxLogInfo(wxT("Starting in server status connect mode (-Sc)."), configFile.c_str());
                 wxString host, database, username, tmps;
-                int sslmode=0,port=0;
+                int sslmode=0,sslverify=0,port=0;
                 wxStringTokenizer tkn(connstr, wxT(" "), wxTOKEN_STRTOK);
                 while (tkn.HasMoreTokens())
                 {
@@ -486,13 +486,28 @@
                         }
                         continue;
                     }
+                    if (str.StartsWith(wxT("sslverify="), &tmps))
+                    {
+                        if (!tmps.Cmp(wxT("cn")))
+                            sslverify = 1;
+                        else if (!tmps.Cmp(wxT("cert")))
+                            sslverify = 2;
+                        else if (!tmps.Cmp(wxT("none")))
+                            sslverify = 3;
+                        else
+                        {
+                            wxMessageBox(_("Unknown SSL verify mode: ") + tmps);
+                            return false;
+                        }
+                        continue;
+                    }
                     wxMessageBox(_("Unknown token in connection string: ") + str);
                     return false;
                 }
                 winSplash->Show(false);
                 dlgSelectConnection dlg(NULL, NULL);
                 dlg.CenterOnParent();
-                conn = dlg.CreateConn(host, database, username, port, sslmode);
+                conn = dlg.CreateConn(host, database, username, port, sslmode, sslverify);
             }
             else
             {
@@ -537,7 +552,7 @@
             {
                 wxLogInfo(wxT("Starting in query tool connect mode (-qc)."), configFile.c_str());
                 wxString host, database, username, tmps;
-                int sslmode=0,port=0;
+                int sslmode=0,sslverify=0,port=0;
                 wxStringTokenizer tkn(connstr, wxT(" "), wxTOKEN_STRTOK);
                 while (tkn.HasMoreTokens())
                 {
@@ -572,13 +587,28 @@
                         }
                         continue;
                     }
+                    if (str.StartsWith(wxT("sslverify="), &tmps))
+                    {
+                        if (!tmps.Cmp(wxT("cn")))
+                            sslverify = 1;
+                        else if (!tmps.Cmp(wxT("cert")))
+                            sslverify = 2;
+                        else if (!tmps.Cmp(wxT("none")))
+                            sslverify = 3;
+                        else
+                        {
+                            wxMessageBox(_("Unknown SSL verify mode: ") + tmps);
+                            return false;
+                        }
+                        continue;
+                    }
                     wxMessageBox(_("Unknown token in connection string: ") + str);
                     return false;
                 }
                 winSplash->Show(false);
                 dlgSelectConnection dlg(NULL, NULL);
                 dlg.CenterOnParent();
-                conn = dlg.CreateConn(host, database, username, port, sslmode);
+                conn = dlg.CreateConn(host, database, username, port, sslmode, sslverify);
             }
             else
             {
Index: pgadmin/frm/frmBackupServer.cpp
===================================================================
--- pgadmin/frm/frmBackupServer.cpp    (revision 7708)
+++ pgadmin/frm/frmBackupServer.cpp    (working copy)
@@ -59,7 +59,8 @@
        environment.Add(wxT("PGPASSWORD=") + ((pgServer *)object)->GetPassword());
 
     // Pass the SSL mode via the environment
-    environment.Add(wxT("PGSSLMODE=") + ((pgServer *)object)->GetConnection()->GetSslModeName());
+    environment.Add(wxT("PGSSLMODE=") + ((pgServer *)object)->GetConnection()->GetSslModeName());
+    environment.Add(wxT("PGSSLVERIFY=") + ((pgServer *)object)->GetConnection()->GetSslVerifyModeName());
 
     // Icon
     SetIcon(wxIcon(backup_xpm));
Index: pgadmin/frm/frmBackup.cpp
===================================================================
--- pgadmin/frm/frmBackup.cpp    (revision 7708)
+++ pgadmin/frm/frmBackup.cpp    (working copy)
@@ -80,6 +80,7 @@

     // Pass the SSL mode via the environment
     environment.Add(wxT("PGSSLMODE=") + object->GetServer()->GetConnection()->GetSslModeName());
+    environment.Add(wxT("PGSSLVERIFY=") + object->GetServer()->GetConnection()->GetSslVerifyModeName());

     // Icon
     SetIcon(wxIcon(backup_xpm));
Index: pgadmin/frm/frmBackupGlobals.cpp
===================================================================
--- pgadmin/frm/frmBackupGlobals.cpp    (revision 7708)
+++ pgadmin/frm/frmBackupGlobals.cpp    (working copy)
@@ -61,7 +61,8 @@
             environment.Add(wxT("PGPASSWORD=") + ((pgServer *)object)->GetPassword());
 
         // Pass the SSL mode via the environment
-        environment.Add(wxT("PGSSLMODE=") + ((pgServer *)object)->GetConnection()->GetSslModeName());
+        environment.Add(wxT("PGSSLMODE=") + ((pgServer *)object)->GetConnection()->GetSslModeName());
+        environment.Add(wxT("PGSSLVERIFY=") + ((pgServer *)object)->GetConnection()->GetSslVerifyModeName());
     }
     else
     {
@@ -70,6 +71,7 @@
 
         // Pass the SSL mode via the environment
         environment.Add(wxT("PGSSLMODE=") + object->GetServer()->GetConnection()->GetSslModeName());
+        environment.Add(wxT("PGSSLVERIFY=") + object->GetServer()->GetConnection()->GetSslVerifyModeName());
 
     }
 
Index: pgadmin/frm/plugins.cpp
===================================================================
--- pgadmin/frm/plugins.cpp    (revision 7708)
+++ pgadmin/frm/plugins.cpp    (working copy)
@@ -243,7 +243,8 @@
             wxSetEnv(wxT("PGPASSWORD"), obj->GetConnection()->GetPassword());
 
         // Pass the SSL mode via the environment
-        wxSetEnv(wxT("PGSSLMODE"), obj->GetConnection()->GetSslModeName());
+        wxSetEnv(wxT("PGSSLMODE"), obj->GetConnection()->GetSslModeName());
+        wxSetEnv(wxT("PGSSLVERIFY"), obj->GetConnection()->GetSslVerifyModeName());
     }
     else
     {
@@ -251,7 +252,8 @@
         execCmd.Replace(wxT("$$HOSTNAME"), wxEmptyString);
         execCmd.Replace(wxT("$$HOSTADDR"), wxEmptyString);
         execCmd.Replace(wxT("$$PORT"), wxEmptyString);
-        execCmd.Replace(wxT("$$SSLMODE"), wxEmptyString);
+        execCmd.Replace(wxT("$$SSLMODE"), wxEmptyString);
+        execCmd.Replace(wxT("$$SSLVERIFY"), wxEmptyString);
         execCmd.Replace(wxT("$$DATABASE"), wxEmptyString);
         execCmd.Replace(wxT("$$USERNAME"), wxEmptyString);
         execCmd.Replace(wxT("$$PASSWORD"), wxEmptyString);
Index: pgadmin/frm/frmRestore.cpp
===================================================================
--- pgadmin/frm/frmRestore.cpp    (revision 7708)
+++ pgadmin/frm/frmRestore.cpp    (working copy)
@@ -115,6 +115,7 @@

     // Pass the SSL mode via the environment
     environment.Add(wxT("PGSSLMODE=") + server->GetConnection()->GetSslModeName());
+    environment.Add(wxT("PGSSLVERIFY=") + server->GetConnection()->GetSslVerifyModeName());

     wxCommandEvent ev;
     OnChangeName(ev);
Index: pgadmin/frm/frmMain.cpp
===================================================================
--- pgadmin/frm/frmMain.cpp    (revision 7708)
+++ pgadmin/frm/frmMain.cpp    (working copy)
@@ -1049,6 +1049,7 @@
             settings->Write(key + wxT("DbRestriction"), server->GetDbRestriction());
             settings->Write(key + wxT("Colour"), server->GetColour());
             settings->Write(key + wxT("SSL"), server->GetSSL());
+            settings->Write(key + wxT("SSLverify"), server->GetSSLverify());

             pgCollection *coll=browser->FindCollection(databaseFactory, server->GetId());
             if (coll)
Index: pgadmin/debugger/dbgPgConn.cpp
===================================================================
--- pgadmin/debugger/dbgPgConn.cpp    (revision 7708)
+++ pgadmin/debugger/dbgPgConn.cpp    (working copy)
@@ -42,19 +42,19 @@
 //
 //    The constructor creates a new thread and connects to the specified server

-dbgPgConn::dbgPgConn(frmDebugger *frame, const wxString &server, const wxString &database, const wxString &userName,
constwxString &password, const wxString &port, int sslmode ) 
+dbgPgConn::dbgPgConn(frmDebugger *frame, const wxString &server, const wxString &database, const wxString &userName,
constwxString &password, const wxString &port, int sslmode, int sslverify ) 
    : m_frame(frame)
 {
-    Init( server, database, userName, password, port, sslmode, true );
+    Init( server, database, userName, password, port, sslmode, sslverify, true );
 }

 dbgPgConn::dbgPgConn(frmDebugger *frame, const dbgConnProp & props, bool startThread )
    : m_frame(frame)
 {
-    Init(  props.m_host, props.m_database, props.m_userName, props.m_password, props.m_port, props.m_sslMode,
startThread); 
+    Init(  props.m_host, props.m_database, props.m_userName, props.m_password, props.m_port, props.m_sslMode,
props.m_sslVerify,startThread ); 
 }

-void dbgPgConn::Init( const wxString &server, const wxString &database, const wxString &username, const wxString
&password,const wxString &port, int sslmode, bool startThread ) 
+void dbgPgConn::Init( const wxString &server, const wxString &database, const wxString &username, const wxString
&password,const wxString &port, int sslmode, int sslverify, bool startThread ) 
 {
     m_pgConn       = NULL;
     m_majorVersion = 0;
@@ -192,7 +192,25 @@
         default:
             break;
     }
+
+    switch (sslverify)
+    {
+        case 1:
+            connectParams.Append(wxT(" sslverify=cn"));
+            break;

+        case 2:
+            connectParams.Append(wxT(" sslverify=cert"));
+            break;
+
+        case 3:
+            connectParams.Append(wxT(" sslverify=none"));
+            break;
+
+        default:
+            break;
+    }
+
     connectParams.Trim(true);
     connectParams.Trim(false);

Index: pgadmin/db/pgConn.cpp
===================================================================
--- pgadmin/db/pgConn.cpp    (revision 7708)
+++ pgadmin/db/pgConn.cpp    (working copy)
@@ -48,7 +48,7 @@
     ((pgConn*)arg)->Notice(message);
 }

-pgConn::pgConn(const wxString& server, const wxString& database, const wxString& username, const wxString& password,
intport, int sslmode, OID oid) 
+pgConn::pgConn(const wxString& server, const wxString& database, const wxString& username, const wxString& password,
intport, int sslmode, int sslverifymode, OID oid) 
 {
     wxString msg, hostip, hostname;

@@ -58,6 +58,7 @@
     save_password = password;
     save_port = port;
     save_sslmode = sslmode;
+    save_sslverifymode = sslverifymode;
     save_oid = oid;

     memset(features, 0, sizeof(features));
@@ -160,6 +161,15 @@
             case 2: connstr.Append(wxT(" requiressl=0"));   break;
         }
     }
+    if (libpqVersion >= 8.4)
+    {
+        switch (sslverifymode)
+        {
+            case 1: connstr.Append(wxT(" sslverify=cn"));   break;
+            case 2: connstr.Append(wxT(" sslverify=cert")); break;
+            case 3: connstr.Append(wxT(" sslverify=none")); break;
+        }
+    }
     connstr.Trim(false);

     // Open the connection
@@ -252,7 +262,7 @@

 pgConn *pgConn::Duplicate()
 {
-    return new pgConn(wxString(save_server), wxString(save_database), wxString(save_username),
wxString(save_password),save_port, save_sslmode, save_oid); 
+    return new pgConn(wxString(save_server), wxString(save_database), wxString(save_username),
wxString(save_password),save_port, save_sslmode, save_sslverifymode, save_oid); 
 }

 // Return the SSL mode name
@@ -262,22 +272,33 @@
     {
         case 1:
             return wxT("require");
-            break;
         case 2:
             return wxT("prefer");
-            break;
         case 3:
             return wxT("allow");
-            break;
         case 4:
             return wxT("disable");
-            break;
         default:
             return wxT("prefer");
-            break;
     }
 }

+// Return the SSL verify mode name
+wxString pgConn::GetSslVerifyModeName()
+{
+    switch (save_sslverifymode)
+    {
+        case 1:
+            return wxT("cn");
+        case 2:
+            return wxT("cert");
+        case 3:
+            return wxT("none");
+        default:
+            return wxT("cn");
+    }
+}
+
 bool pgConn::GetIsEdb()
 {
     // to retrieve edb flag
@@ -481,9 +502,14 @@
         {
             if (!strcmp(co->keyword, "sslmode"))
             {
-                libpqVersion=7.4;
-                break;
+                if (libpqVersion < 7.4)
+                    libpqVersion=7.4;
             }
+            if (!strcmp(co->keyword, "sslverify"))
+            {
+                if (libpqVersion < 8.4)
+                    libpqVersion=8.4;
+            }
             co++;
         }
         PQconninfoFree(cio);
Index: pgadmin/schema/pgServer.cpp
===================================================================
--- pgadmin/schema/pgServer.cpp    (revision 7708)
+++ pgadmin/schema/pgServer.cpp    (working copy)
@@ -39,7 +39,7 @@

 #define DEFAULT_PG_DATABASE wxT("postgres")

-pgServer::pgServer(const wxString& newName, const wxString& newDescription, const wxString& newDatabase, const
wxString&newUsername, int newPort, bool _storePwd, bool _restore, int _ssl, const wxString &_colour) 
+pgServer::pgServer(const wxString& newName, const wxString& newDescription, const wxString& newDatabase, const
wxString&newUsername, int newPort, bool _storePwd, bool _restore, int _ssl, int _sslverify, const wxString &_colour) 
 : pgObject(serverFactory, newName)
 {
     description = newDescription;
@@ -47,6 +47,7 @@
     username = newUsername;
     port = newPort;
     ssl=_ssl;
+    sslverify=_sslverify;
     colour = _colour;
     serverIndex=0;

@@ -137,7 +138,7 @@
         dbName = GetDatabaseName();
         oid = dbOid;
     }
-    pgConn *conn=new pgConn(GetName(), dbName, username, password, port, ssl, oid);
+    pgConn *conn=new pgConn(GetName(), dbName, username, password, port, ssl, sslverify, oid);

     if (conn && conn->GetStatus() != PGCONN_OK)
     {
@@ -614,21 +615,21 @@

         if (database.IsEmpty())
         {
-            conn = new pgConn(GetName(), DEFAULT_PG_DATABASE, username, password, port, ssl);
+            conn = new pgConn(GetName(), DEFAULT_PG_DATABASE, username, password, port, ssl, sslverify);
             if (conn->GetStatus() == PGCONN_OK)
                 database=DEFAULT_PG_DATABASE;
             else if (conn->GetStatus() == PGCONN_BAD && conn->GetLastError().Find(
                                 wxT("database \"") DEFAULT_PG_DATABASE wxT("\" does not exist")) >= 0)
             {
                 delete conn;
-                conn = new pgConn(GetName(), wxT("template1"), username, password, port, ssl);
+                conn = new pgConn(GetName(), wxT("template1"), username, password, port, ssl, sslverify);
                 if (conn && conn->GetStatus() == PGCONN_OK)
                     database=wxT("template1");
             }
         }
         else
         {
-            conn = new pgConn(GetName(), database, username, password, port, ssl);
+            conn = new pgConn(GetName(), database, username, password, port, ssl, sslverify);
             if (!conn)
             {
                 form->EndMsg(false);
@@ -933,6 +934,17 @@
                     }
                     properties->AppendItem(_("SSL Mode"), sslMode);
                 }
+                if (sslverify > 0)
+                {
+                    wxString sslVerifyMode;
+                    switch (sslverify)
+                    {
+                        case 1: sslVerifyMode = _("Full verification"); break;
+                        case 2: sslVerifyMode = _("Certificate only"); break;
+                        case 3: sslVerifyMode = _("No verification"); break;
+                    }
+                    properties->AppendItem(_("SSL Verify Mode"), sslVerifyMode);
+                }
             }
 #endif
         }
@@ -1079,7 +1091,7 @@
 {
     long numServers=settings->Read(wxT("Servers/Count"), 0L);

-    long loop, port, ssl=0;
+    long loop, port, ssl=0, sslverify=0;
     wxString key, servername, description, database, username, lastDatabase, lastSchema, storePwd, restore, serviceID,
discoveryID,dbRestriction, colour; 
     pgServer *server=0;

@@ -1118,10 +1130,11 @@
         // SSL mode
 #ifdef SSL
         settings->Read(key + wxT("SSL"), &ssl, 0);
+        settings->Read(key + wxT("SSLverify"), &sslverify, 0);
 #endif

         // Add the Server node
-        server = new pgServer(servername, description, database, username, port, StrToBool(storePwd),
StrToBool(restore),ssl); 
+        server = new pgServer(servername, description, database, username, port, StrToBool(storePwd),
StrToBool(restore),ssl, sslverify); 
         server->iSetLastDatabase(lastDatabase);
         server->iSetLastSchema(lastSchema);
         server->iSetServiceID(serviceID);
Index: pgadmin/dlg/dlgServer.cpp
===================================================================
--- pgadmin/dlg/dlgServer.cpp    (revision 7708)
+++ pgadmin/dlg/dlgServer.cpp    (working copy)
@@ -29,6 +29,7 @@
 #define cbDatabase      CTRL_COMBOBOX("cbDatabase")
 #define txtPort         CTRL_TEXT("txtPort")
 #define cbSSL           CTRL_COMBOBOX("cbSSL")
+#define cbSSLverify     CTRL_COMBOBOX("cbSSLverify")
 #define txtUsername     CTRL_TEXT("txtUsername")
 #define stTryConnect    CTRL_STATIC("stTryConnect")
 #define chkTryConnect   CTRL_CHECKBOX("chkTryConnect")
@@ -53,6 +54,7 @@
     EVT_TEXT(XRCID("txtUsername"),                  dlgProperty::OnChange)
     EVT_TEXT(XRCID("txtDbRestriction"),             dlgServer::OnChangeRestr)
     EVT_COMBOBOX(XRCID("cbSSL"),                    dlgProperty::OnChange)
+    EVT_COMBOBOX(XRCID("cbSSLverify"),              dlgProperty::OnChange)
     EVT_CHECKBOX(XRCID("chkStorePwd"),              dlgProperty::OnChange)
     EVT_CHECKBOX(XRCID("chkRestore"),               dlgProperty::OnChange)
     EVT_CHECKBOX(XRCID("chkTryConnect"),            dlgServer::OnChangeTryConnect)
@@ -85,6 +87,8 @@
     txtPort->SetValue(NumToStr((long)settings->GetLastPort()));
     if (!cbSSL->IsEmpty())
         cbSSL->SetSelection(settings->GetLastSSL());
+    if (!cbSSLverify->IsEmpty())
+        cbSSLverify->SetSelection(settings->GetLastSSLverify());
     txtUsername->SetValue(settings->GetLastUsername());

     chkTryConnect->SetValue(true);
@@ -105,6 +109,7 @@
         settings->SetLastDatabase(cbDatabase->GetValue());
         settings->SetLastPort(StrToLong(txtPort->GetValue()));
         settings->SetLastSSL(cbSSL->GetCurrentSelection());
+        settings->SetLastSSLverify(cbSSLverify->GetCurrentSelection());
         settings->SetLastUsername(txtUsername->GetValue());
     }
 }
@@ -142,6 +147,7 @@
         }
         server->iSetPort(StrToLong(txtPort->GetValue()));
         server->iSetSSL(cbSSL->GetCurrentSelection());
+        server->iSetSSLverify(cbSSLverify->GetCurrentSelection());
         server->iSetDatabase(cbDatabase->GetValue());
         server->iSetUsername(txtUsername->GetValue());
         server->iSetStorePwd(chkStorePwd->GetValue());
@@ -215,6 +221,7 @@
 int dlgServer::Go(bool modal)
 {
     cbSSL->Append(wxT(" "));
+    cbSSLverify->Append(wxT(" "));

 #ifdef SSL
     cbSSL->Append(_("require"));
@@ -225,6 +232,13 @@
         cbSSL->Append(_("allow"));
         cbSSL->Append(_("disable"));
     }
+
+    if (pgConn::GetLibpqVersion() >= 8.4)
+    {
+        cbSSLverify->Append(_("Full verification"));
+        cbSSLverify->Append(_("Certificate only"));
+        cbSSLverify->Append(_("No verification"));
+    }
 #endif

     if (server)
@@ -235,6 +249,7 @@
         txtService->SetValue(server->GetServiceID());
         txtPort->SetValue(NumToStr((long)server->GetPort()));
         cbSSL->SetSelection(server->GetSSL());
+        cbSSLverify->SetSelection(server->GetSSLverify());
         cbDatabase->SetValue(server->GetDatabaseName());
         txtUsername->SetValue(server->GetUsername());
         chkStorePwd->SetValue(server->GetStorePwd());
@@ -250,6 +265,7 @@
             cbDatabase->Disable();
             txtPort->Disable();
             cbSSL->Disable();
+            cbSSLverify->Disable();
             txtUsername->Disable();
             chkStorePwd->Disable();
         }
@@ -282,7 +298,8 @@
     pgObject *obj=new pgServer(GetName(), txtDescription->GetValue(), cbDatabase->GetValue(),
         txtUsername->GetValue(), StrToLong(txtPort->GetValue()),
         chkTryConnect->GetValue() && chkStorePwd->GetValue(),
-        chkRestore->GetValue(), cbSSL->GetCurrentSelection(), txtColour->GetValue());
+        chkRestore->GetValue(), cbSSL->GetCurrentSelection(),
+        cbSSLverify->GetCurrentSelection(), txtColour->GetValue());

     return obj;
 }
@@ -320,6 +337,7 @@
                || cbDatabase->GetValue() != server->GetDatabaseName()
                || txtUsername->GetValue() != server->GetUsername()
                || cbSSL->GetCurrentSelection() != server->GetSSL()
+               || cbSSLverify->GetCurrentSelection() != server->GetSSLverify()
                || chkStorePwd->GetValue() != server->GetStorePwd()
                || chkRestore->GetValue() != server->GetRestore()
                || txtDbRestriction->GetValue() != server->GetDbRestriction()
@@ -332,6 +350,7 @@
 #else
     bool isPipe = (name.IsEmpty() || name.StartsWith(wxT("/")));
     cbSSL->Enable(!isPipe);
+    cbSSLverify->Enable(!isPipe);
 #endif
     CheckValid(enable, !txtDescription->GetValue().IsEmpty(), _("Please specify description."));
     CheckValid(enable, StrToLong(txtPort->GetValue()) > 0, _("Please specify port."));
Index: pgadmin/dlg/dlgSelectConnection.cpp
===================================================================
--- pgadmin/dlg/dlgSelectConnection.cpp    (revision 7708)
+++ pgadmin/dlg/dlgSelectConnection.cpp    (working copy)
@@ -203,10 +203,10 @@
     }
 }
 
-pgConn *dlgSelectConnection::CreateConn(wxString& server, wxString& dbname, wxString& username, int port, int sslmode,
boolwriteMRU)
 
+pgConn *dlgSelectConnection::CreateConn(wxString& server, wxString& dbname, wxString& username, int port, int sslmode,
intsslverify, bool writeMRU)
 
 {
     pgConn *newconn;
-    newconn = new pgConn(server, dbname, username, wxT(""), port, sslmode);
+    newconn = new pgConn(server, dbname, username, wxT(""), port, sslmode, sslverify);
     if (newconn->GetStatus() != PGCONN_OK &&
         newconn->GetLastError().Cmp(wxString(PQnoPasswordSupplied, wxConvUTF8)) == 0)
     {
@@ -220,7 +220,7 @@
         if (dlg.Go() != wxID_OK)
             return NULL;
 
-        newconn = new pgConn(server, dbname, username, dlg.GetPassword(), port, sslmode);
+        newconn = new pgConn(server, dbname, username, dlg.GetPassword(), port, sslmode, sslverify);
     }
 
     if (newconn)
Index: pgadmin/ui/dlgServer.xrc
===================================================================
--- pgadmin/ui/dlgServer.xrc    (revision 7708)
+++ pgadmin/ui/dlgServer.xrc    (working copy)
@@ -66,12 +66,28 @@
                   <border>4</border>
                 </object>
                 <object class="sizeritem">
-                  <object class="wxComboBox" name="cbSSL">
+                 <object class="wxGridSizer">
+                  <cols>2</cols>
+                  <rows>2</rows>
+                  <growablecols>1</growablecols>
+                  <object class="sizeritem">
+                   <object class="wxComboBox" name="cbSSL">
                     <style>wxCB_READONLY|wxCB_DROPDOWN</style>
                     <content/>
+                   </object>
+                   <flag>wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag>
+                   <border>4</border>
                   </object>
-                  <flag>wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag>
-                  <border>4</border>
+                  <object class="sizeritem">
+                   <object class="wxComboBox" name="cbSSLverify">
+                    <style>wxCB_READONLY|wxCB_DROPDOWN</style>
+                    <content/>
+                   </object>
+                   <flag>wxEXPAND|wxALIGN_CENTRE_VERTICAL|wxTOP|wxLEFT|wxRIGHT</flag>
+                   <border>4</border>
+                  </object>
+                 </object>
+                 <flag>wxGROW</flag>
                 </object>
                 <object class="sizeritem">
                   <object class="wxStaticText" name="stDatabase">
@@ -258,4 +274,4 @@
       </object>
     </object>
   </object>
-</resource>
\ No newline at end of file
+</resource>

Re: Support for sslverify

От
Dave Page
Дата:
On Mon, Mar 16, 2009 at 6:31 PM, Magnus Hagander <magnus@hagander.net> wrote:

> This look better?

Yep - the only issues I spotted are:

- Typo in dlgSelectConnection.h. You can't miss it!!

- No change to plugins.ini, which documents the plugins interface.

> (I haven't actually tested the backup stuff :-P But it builds..)

Looks as it should to me! But I haven't tested either, so please do so.

> I also noticed we have windows linebreaks in at least one file in the
> debugger directory...

Feel free to fix :-p


--
Dave Page
EnterpriseDB UK:   http://www.enterprisedb.com