225
242
* nice not to send it to 1.0 servers. Sadly, it's the first RPC
226
243
* we send, so we don't know what version the server is... yet.
228
char *locale = setlocale(LC_MESSAGES, NULL);
229
if (locale != NULL && locale[0] != '\0' && strcmp(locale, "C") != 0 &&
230
strcmp(locale, "POSIX") != 0) {
232
mDelegate->SetBusy(_("Setting client locale..."));
246
const char *locale = setlocale(LC_MESSAGES, NULL);
248
char locale[32] = { '\0' };
249
CFArrayRef langs = CFLocaleCopyPreferredLanguages();
250
CFStringRef localeStr = (CFStringRef)CFArrayGetValueAtIndex(langs, 0);
251
if (CFStringGetCString(localeStr, locale, sizeof(locale),
252
kCFStringEncodingASCII)) {
254
if (locale != NULL && locale[0] != '\0' && strcmp(locale, "C") != 0 &&
255
strcmp(locale, "POSIX") != 0) {
256
mXml->SetLocale(locale,
257
boost::bind(&Broker::OnInitialRPCAbort, this, _1, _2),
258
boost::bind(&Broker::OnLocaleSet, this));
234
mXml->SetLocale(locale,
235
boost::bind(&Broker::OnInitialRPCAbort, this, _1, _2),
236
boost::bind(&Broker::OnLocaleSet, this));
258
284
Broker::AcceptDisclaimer()
261
mDelegate->SetBusy(_("Accepting disclaimer..."));
286
mAcceptedDisclaimer = true;
263
287
if (mCertState == CERT_REQUESTED) {
265
289
* Pre-login message is enabled, and the server asked us for a
266
290
* cert. We'll reset our connections, and when we do the accept
267
291
* disclaimer RPC, we'll get asked for a cert again.
269
Log("Accepting disclaimer and cert was requested; "
270
"enabling cert response and accepting disclaimer.\n");
271
mXml->ResetConnections();
272
mCertState = CERT_SHOULD_RESPOND;
274
mXml->QueueRequests();
275
mXml->AcceptDisclaimer(
276
boost::bind(&Broker::OnInitialRPCAbort, this, _1, _2),
277
boost::bind(&Broker::OnAuthResult, this, _1, _2));
280
mXml->SendQueuedRequests();
293
Log("Accepting disclaimer and cert was requested; prompting user for a "
296
mDelegate->RequestCertificate(mTrustedIssuers);
299
mXml->QueueRequests();
300
mXml->AcceptDisclaimer(
301
boost::bind(&Broker::OnInitialRPCAbort, this, _1, _2),
302
boost::bind(&Broker::OnAuthResult, this, _1, _2));
305
mXml->SendQueuedRequests();
311
*-----------------------------------------------------------------------------
313
* cdk::Broker::SubmitCertificate --
315
* Set the certificate and private key to use when
316
* authenticating, and smart card PIN and reader name (if
319
* NULL cert or key signifies not to authenticate using a
326
* Authentication will continue.
328
*-----------------------------------------------------------------------------
332
Broker::SubmitCertificate(X509 *cert, // IN/OPT
333
EVP_PKEY *key, // IN/OPT
334
const char *pin, // IN/OPT
335
const Util::string &reader) // IN/OPT
337
ASSERT(mCertState == CERT_REQUESTED);
340
ASSERT(!mSmartCardPin);
341
ASSERT(mSmartCardReader.empty());
345
mSmartCardPin = g_strdup(pin);
346
mSmartCardReader = reader;
348
mCertState = CERT_SHOULD_RESPOND;
349
mXml->ResetConnections();
351
if (mAcceptedDisclaimer) {
352
Log("Accepting disclaimer with cert response enabled.\n");
353
mXml->QueueRequests();
354
mXml->AcceptDisclaimer(
355
boost::bind(&Broker::OnInitialRPCAbort, this, _1, _2),
356
boost::bind(&Broker::OnAuthResult, this, _1, _2));
359
mXml->SendQueuedRequests();
361
Log("Getting configuration with cert response enabled.\n");
913
985
OnAuthInfoPinChange(authInfo.params);
915
987
case BrokerXml::AUTH_SECURID_WAIT:
916
App::ShowDialog(GTK_MESSAGE_INFO,
917
_("Your new RSA SecurID PIN has been set.\n\n"
918
"Please wait for the next tokencode to appear"
919
" on your RSA SecurID token, then continue."));
988
BaseApp::ShowInfo(_("Your new RSA SecurID PIN has been set"),
989
_("Please wait for the next tokencode to appear"
990
" on your RSA SecurID token, then continue."));
921
992
mDelegate->RequestPasscode(mUsername, false);
939
1010
case BrokerXml::AUTH_CERT_AUTH:
940
Log("Queueing idle cert auth response\n");
941
Poll_CallbackRemove(POLL_CS_MAIN, 0, OnIdleSubmitCertAuth, this,
943
Poll_Callback(POLL_CS_MAIN, 0, OnIdleSubmitCertAuth, this,
944
POLL_REALTIME, 0, NULL);
1011
mXml->QueueRequests();
1012
mXml->SubmitCertAuth(
1013
true, mSmartCardPin, mSmartCardReader,
1014
boost::bind(&Broker::OnInitialRPCAbort, this, _1, _2),
1015
boost::bind(&Broker::OnAuthResult, this, _1, _2));
1018
mXml->SendQueuedRequests();
1019
ClearSmartCardPinAndReader();
947
App::ShowDialog(GTK_MESSAGE_ERROR,
948
_("Unknown authentication method requested: %s"),
949
authInfo.name.c_str());
1022
BaseApp::ShowError(CDK_ERR_AUTH_UNKNOWN_METHOD_REQUEST,
1023
_("Unknown authentication method requested"),
1024
_("Received unknown request \"%s\" from the broker"),
1025
authInfo.name.c_str());
950
1026
if (mDelegate) {
951
1027
mDelegate->RequestBroker();
995
1071
// Ignore other param names, like "error" (which we've already handled).
997
1073
if (!userSelectable && pin.empty()) {
998
App::ShowDialog(GTK_MESSAGE_ERROR,
999
_("Invalid PIN Change response sent by server."));
1074
BaseApp::ShowError(CDK_ERR_INVALID_SERVER_RESPONSE,
1075
_("Invalid response from server"),
1076
_("Invalid PIN Change response sent by server."));
1000
1077
} else if (mDelegate) {
1001
1078
mDelegate->RequestPinChange(pin, message, userSelectable);
1375
1465
Broker::OnAbort(bool cancelled, // IN
1376
1466
Util::exception err) // IN
1468
bool showGenericError = false;
1378
1470
// Update list to reflect reset Desktop ConnectionState values on failure.
1379
1471
if (mDelegate) {
1380
1472
mDelegate->UpdateDesktops();
1382
mDelegate->SetReady();
1384
1474
if (cancelled) {
1387
1478
if (err.code() == ERR_AUTHENTICATION_FAILED) {
1388
App::ShowDialog(GTK_MESSAGE_ERROR, _("Error authenticating: %s"),
1479
BaseApp::ShowError(CDK_ERR_AUTH_ERROR, _("Error authenticating"), "%s", err.what());
1390
1480
if (mDelegate) {
1391
1481
mDelegate->RequestBroker();
1411
1501
mTunnel && mTunnel->GetIsBypassed() &&
1412
1502
!mTunnelMonitor.ShouldThrottle()) {
1504
* The linux vdm client is hacked to attempt reestablishing a
1505
* tunnel connection if the existing tunnel connection was
1506
* offline-bypassed and the get-destkop-connection fails with
1507
* "DESKTOP_LAUNCH_ERROR". This covers the case where the
1508
* connection is reestablished and the user attempts to connect
1509
* to a remote desktop.
1414
1512
* XXX: Going this route is very slow, as the broker waits for tunnel
1415
1513
* setup before failing the desktop connection.
1517
} else if (err.code() == ERR_NOT_ENTITLED) {
1518
// This probably means we have out-of-date information; refresh.
1520
showGenericError = true;
1521
} else if (err.code() == ERR_TUNNEL_ERROR) {
1522
ASSERT(mTunnelState == TUNNEL_GETTING_INFO);
1524
showGenericError = true;
1420
if (err.code() == ERR_NOT_ENTITLED) {
1421
// This probably means we have out-of-date information; refresh.
1424
App::ShowDialog(GTK_MESSAGE_ERROR, "%s", _(err.what()));
1526
showGenericError = true;
1529
if (showGenericError) {
1530
Util::string errorDetails = err.details();
1531
if (errorDetails.empty()) {
1532
BaseApp::ShowError(CDK_ERR_AUTH_ERROR, _("An error occurred"),
1533
"%s", _(err.what()));
1535
BaseApp::ShowError(CDK_ERR_AUTH_ERROR, _(err.what()), "%s",
1536
_(errorDetails.c_str()));
1540
mDelegate->SetReady();
1500
1617
mXml->SendQueuedRequests();
1620
} else if (err.code() == ERR_BASICHTTP_ERROR_SSL_CONNECT_ERROR &&
1621
mCertState == CERT_DID_RESPOND) {
1622
mXml->ResetConnections();
1623
if (mAcceptedDisclaimer) {
1624
Log("Accepting disclaimer and cert response failed; "
1625
"disabling cert response and accepting disclaimer "
1627
mXml->QueueRequests();
1628
mXml->AcceptDisclaimer(
1629
boost::bind(&Broker::OnInitialRPCAbort, this, _1, _2),
1630
boost::bind(&Broker::OnAuthResult, this, _1, _2));
1633
mXml->SendQueuedRequests();
1635
Log("No disclaimer seen, but cert response failed; just trying to "
1636
"GetConfiguration() again.\n");
1599
1736
* we should do so.
1601
1738
mCertState = CERT_REQUESTED;
1741
* Cache the issuers since they almost certainly won't change
1742
* between this request and the one we later use to actually
1743
* do certificate authentication.
1745
STACK_OF(X509_NAME) *issuers = SSL_get_client_CA_list(ssl);
1746
ASSERT(mTrustedIssuers.empty());
1747
for (int i = 0; i < sk_X509_NAME_num(issuers); i++) {
1748
X509_NAME *issuer = sk_X509_NAME_value(issuers, i);
1750
char *dispName = X509_NAME_oneline(issuer, NULL, 0);
1751
if (dispName && strcmp(dispName, "NO X509_NAME")) {
1752
mTrustedIssuers.push_back(dispName);
1754
OPENSSL_free(dispName);
1602
1758
// fall through...
1603
1759
case CERT_DID_RESPOND:
1604
1760
case CERT_REQUESTED:
1606
1762
case CERT_SHOULD_RESPOND:
1767
if (!*x509 || !*privKey) {
1608
1768
ClearSmartCardPinAndReader();
1609
CertAuthInfo info = mDelegate->GetCertAuthInfo(ssl);
1611
*privKey = info.key;
1612
mSmartCardPin = info.pin;
1613
mSmartCardReader = info.reader;
1614
if (!*x509 || !*privKey) {
1615
ClearSmartCardPinAndReader();
1618
1770
mCertState = CERT_DID_RESPOND;
1658
1810
*-----------------------------------------------------------------------------
1660
* cdk::Broker::OnIdleSubmitCertAuth --
1662
* Submit a cert auth response in an idle handler. This is
1663
* needed in the case where we don't have a disclaimer, because
1664
* the current request is the one which sets our cookie.
1667
* FALSE to remove this callback.
1670
* Accepts the cert-auth response.
1672
*-----------------------------------------------------------------------------
1676
Broker::OnIdleSubmitCertAuth(void *data) // IN
1678
Broker *that = reinterpret_cast<Broker *>(data);
1681
if (that->mDelegate) {
1682
that->mDelegate->SetBusy(_("Logging in..."));
1685
that->mXml->QueueRequests();
1686
that->mXml->SubmitCertAuth(
1687
true, that->mSmartCardPin, that->mSmartCardReader,
1688
boost::bind(&Broker::OnInitialRPCAbort, that, _1, _2),
1689
boost::bind(&Broker::OnAuthResult, that, _1, _2));
1691
that->GetDesktops();
1692
that->mXml->SendQueuedRequests();
1693
that->ClearSmartCardPinAndReader();
1812
* cdk::Broker::GetDesktopName --
1814
* Runs through the list of desktops and if the desktop with the given ID
1815
* is in the list, returns it's name.
1818
* Util::string holding the desktop name, or empty.
1823
*-----------------------------------------------------------------------------
1827
Broker::GetDesktopName(Util::string desktopID) // IN
1829
for (std::vector<Desktop *>::iterator iter = mDesktops.begin();
1830
iter != mDesktops.end(); iter++) {
1831
if ((*iter)->GetID() == desktopID) {
1832
return (*iter)->GetName();
1841
*-----------------------------------------------------------------------------
1843
* Broker::CreateNewXmlConnection --
1845
* Creates a new instance of the object used for sending XML requests.
1846
* This is a virtual method so derived classes can create a specialization
1847
* of BrokerXML instead.
1850
* A new instance of BrokerXml* .
1853
* The caller is responsible for freeing the returned object.
1855
*-----------------------------------------------------------------------------
1859
Broker::CreateNewXmlConnection(const Util::string &hostname, // IN
1863
return new BrokerXml(hostname, port, secure);
1868
*-----------------------------------------------------------------------------
1870
* Broker::GetSupportBrokerUrl --
1872
* Returns the URL of the connection server we are connected to.
1875
* Util::string with the protocol, hostname, and port of the connection
1881
*-----------------------------------------------------------------------------
1885
Broker::GetSupportBrokerUrl()
1888
return Util::Format("%s://%s:%d", GetSecure() ? "https" : "http",
1889
GetHostname().c_str(), GetPort());
1894
*-----------------------------------------------------------------------------
1896
* Broker::CancelRequests --
1898
* Cancels all outstanding requests.
1901
* The number of requests that were cancelled.
1906
*-----------------------------------------------------------------------------
1910
Broker::CancelRequests()
1915
* If the tunnel's state was CONNECTING, but we tried to connect to a
1916
* desktop, when the tunnel finishes connecting, it will try to launch the
1917
* desktop. In order to avoid this, set mDesktop to NULL so this race
1918
* condition won't happen. See bz 514312.
1920
if (mDesktop && mTunnelState == TUNNEL_CONNECTING) {
1924
return mXml->CancelRequests();