Tue, 25 Dec 2007 23:00:27 +0000
merge of '95cdc03c44be5a7431261b6ca3e341c0e92fa549'
and 'aab79eb566a1a2d996ab79245c0beb2dc8aadc22'
--- a/configure.ac Tue Dec 25 22:59:15 2007 +0000 +++ b/configure.ac Tue Dec 25 23:00:27 2007 +0000 @@ -678,7 +678,6 @@ PKG_CHECK_MODULES(MEANWHILE, [meanwhile >= 1.0.0 meanwhile < 2.0.0], [ have_meanwhile="yes" ], [ - AC_MSG_RESULT(no) have_meanwhile="no" ]) AC_SUBST(MEANWHILE_CFLAGS) @@ -697,7 +696,6 @@ avahiincludes="yes" avahilibs="yes" ], [ - AC_MSG_RESULT(no) avahiincludes="no" avahilibs="no" ]) @@ -742,7 +740,6 @@ silcincludes="yes" silcclient="yes" ], [ - AC_MSG_RESULT(no) have_silc="no" ]) if test "x$have_silc" = "xno"; then @@ -751,7 +748,6 @@ silc10includes="yes" silc10client="yes" ], [ - AC_MSG_RESULT(no) have_silc="no" ]) dnl If silcclient.pc wasn't found, check for just silc.pc @@ -761,7 +757,6 @@ silc10includes="yes" silc10client="yes" ], [ - AC_MSG_RESULT(no) have_silc="no" ]) fi @@ -1154,7 +1149,6 @@ AC_SUBST(DBUS_LIBS) enable_dbus=yes ], [ - AC_MSG_RESULT(no) enable_dbus=no ])
--- a/libpurple/account.c Tue Dec 25 22:59:15 2007 +0000 +++ b/libpurple/account.c Tue Dec 25 23:00:27 2007 +0000 @@ -1645,7 +1645,7 @@ if (status == NULL) { purple_debug_error("account", - "Invalid status ID %s for account %s (%s)\n", + "Invalid status ID '%s' for account %s (%s)\n", status_id, purple_account_get_username(account), purple_account_get_protocol_id(account)); return;
--- a/libpurple/blist.h Tue Dec 25 22:59:15 2007 +0000 +++ b/libpurple/blist.h Tue Dec 25 23:00:27 2007 +0000 @@ -680,7 +680,8 @@ * * @param g The group * - * @return A list of purple_accounts + * @return A GSList of accounts (which must be freed), or NULL if the group + * has no accounts. */ GSList *purple_group_get_accounts(PurpleGroup *g);
--- a/libpurple/certificate.c Tue Dec 25 22:59:15 2007 +0000 +++ b/libpurple/certificate.c Tue Dec 25 23:00:27 2007 +0000 @@ -1228,6 +1228,9 @@ } static void +x509_tls_cached_unknown_peer(PurpleCertificateVerificationRequest *vrq); + +static void x509_tls_cached_cert_in_cache(PurpleCertificateVerificationRequest *vrq) { /* TODO: Looking this up by name over and over is expensive. @@ -1268,8 +1271,8 @@ } else { purple_debug_info("certificate/x509/tls_cached", "Peer cert did NOT match cached\n"); - /* vrq now becomes the problem of cert_changed */ - x509_tls_cached_peer_cert_changed(vrq); + /* vrq now becomes the problem of the user */ + x509_tls_cached_unknown_peer(vrq); } purple_certificate_destroy(cached_crt); @@ -1280,7 +1283,9 @@ /* For when we've never communicated with this party before */ /* TODO: Need ways to specify possibly multiple problems with a cert, or at least reprioritize them. For example, maybe the signature ought to be - checked BEFORE the hostname checking? */ + checked BEFORE the hostname checking? + Stu thinks we should check the signature before the name, so we do now. + The above TODO still stands. */ static void x509_tls_cached_unknown_peer(PurpleCertificateVerificationRequest *vrq) { @@ -1292,35 +1297,6 @@ peer_crt = (PurpleCertificate *) chain->data; - /* First, check that the hostname matches */ - if ( ! purple_certificate_check_subject_name(peer_crt, - vrq->subject_name) ) { - gchar *sn = purple_certificate_get_subject_name(peer_crt); - gchar *msg; - - purple_debug_info("certificate/x509/tls_cached", - "Name mismatch: Certificate given for %s " - "has a name of %s\n", - vrq->subject_name, sn); - - /* Prompt the user to authenticate the certificate */ - /* TODO: Provide the user with more guidance about why he is - being prompted */ - /* vrq will be completed by user_auth */ - msg = g_strdup_printf(_("The certificate presented by \"%s\" " - "claims to be from \"%s\" instead. " - "This could mean that you are not " - "connecting to the service you " - "believe you are."), - vrq->subject_name, sn); - - x509_tls_cached_user_auth(vrq,msg); - - g_free(sn); - g_free(msg); - return; - } /* if (name mismatch) */ - /* TODO: Figure out a way to check for a bad signature, as opposed to "not self-signed" */ if ( purple_certificate_signed_by(peer_crt, peer_crt) ) { @@ -1341,7 +1317,7 @@ g_free(msg); return; - } /* if (name mismatch) */ + } /* if (self signed) */ /* Next, check that the certificate chain is valid */ if ( ! purple_certificate_check_signature_chain(chain) ) { @@ -1440,6 +1416,35 @@ return; } /* if (CA signature not good) */ + /* Last, check that the hostname matches */ + if ( ! purple_certificate_check_subject_name(peer_crt, + vrq->subject_name) ) { + gchar *sn = purple_certificate_get_subject_name(peer_crt); + gchar *msg; + + purple_debug_info("certificate/x509/tls_cached", + "Name mismatch: Certificate given for %s " + "has a name of %s\n", + vrq->subject_name, sn); + + /* Prompt the user to authenticate the certificate */ + /* TODO: Provide the user with more guidance about why he is + being prompted */ + /* vrq will be completed by user_auth */ + msg = g_strdup_printf(_("The certificate presented by \"%s\" " + "claims to be from \"%s\" instead. " + "This could mean that you are not " + "connecting to the service you " + "believe you are."), + vrq->subject_name, sn); + + x509_tls_cached_user_auth(vrq,msg); + + g_free(sn); + g_free(msg); + return; + } /* if (name mismatch) */ + /* If we reach this point, the certificate is good. */ /* Look up the local cache and store it there for future use */ tls_peers = purple_certificate_find_pool(x509_tls_cached.scheme_name,
--- a/libpurple/cmds.h Tue Dec 25 22:59:15 2007 +0000 +++ b/libpurple/cmds.h Tue Dec 25 23:00:27 2007 +0000 @@ -30,25 +30,20 @@ /**************************************************************************/ /*@{*/ -typedef enum _PurpleCmdPriority PurpleCmdPriority; -typedef enum _PurpleCmdFlag PurpleCmdFlag; -typedef enum _PurpleCmdStatus PurpleCmdStatus; -typedef enum _PurpleCmdRet PurpleCmdRet; - -enum _PurpleCmdStatus { +typedef enum _PurpleCmdStatus { PURPLE_CMD_STATUS_OK, PURPLE_CMD_STATUS_FAILED, PURPLE_CMD_STATUS_NOT_FOUND, PURPLE_CMD_STATUS_WRONG_ARGS, PURPLE_CMD_STATUS_WRONG_PRPL, PURPLE_CMD_STATUS_WRONG_TYPE, -}; +} PurpleCmdStatus; -enum _PurpleCmdRet { +typedef enum _PurpleCmdRet { PURPLE_CMD_RET_OK, /**< Everything's okay. Don't look for another command to call. */ PURPLE_CMD_RET_FAILED, /**< The command failed, but stop looking.*/ PURPLE_CMD_RET_CONTINUE, /**< Continue, looking for other commands with the same name to call. */ -}; +} PurpleCmdRet; #define PURPLE_CMD_FUNC(func) ((PurpleCmdFunc)func) @@ -56,7 +51,7 @@ gchar **args, gchar **error, void *data); typedef guint PurpleCmdId; -enum _PurpleCmdPriority { +typedef enum _PurpleCmdPriority { PURPLE_CMD_P_VERY_LOW = -1000, PURPLE_CMD_P_LOW = 0, PURPLE_CMD_P_DEFAULT = 1000, @@ -65,7 +60,7 @@ PURPLE_CMD_P_ALIAS = 4000, PURPLE_CMD_P_HIGH = 5000, PURPLE_CMD_P_VERY_HIGH = 6000, -}; +} PurpleCmdPriority; /** Flags used to set various properties of commands. Every command should * have at least one of #PURPLE_CMD_FLAG_IM and #PURPLE_CMD_FLAG_CHAT set in @@ -73,7 +68,7 @@ * * @see purple_cmd_register */ -enum _PurpleCmdFlag { +typedef enum _PurpleCmdFlag { /** Command is usable in IMs. */ PURPLE_CMD_FLAG_IM = 0x01, /** Command is usable in multi-user chats. */ @@ -82,7 +77,7 @@ PURPLE_CMD_FLAG_PRPL_ONLY = 0x04, /** Incorrect arguments to this command should be accepted anyway. */ PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS = 0x08, -}; +} PurpleCmdFlag; /*@}*/
--- a/libpurple/prefs.c Tue Dec 25 22:59:15 2007 +0000 +++ b/libpurple/prefs.c Tue Dec 25 23:00:27 2007 +0000 @@ -438,19 +438,6 @@ g_free(filename); prefs_loaded = TRUE; - /* I introduced a bug in 2.0.0beta2. This fixes the broken - * scores on upgrade. This can be removed sometime shortly - * after 2.0.0 final is released. -- rlaager */ - if (purple_prefs_get_int("/purple/status/scores/offline") == -500 && - purple_prefs_get_int("/purple/status/scores/available") == 100 && - purple_prefs_get_int("/purple/status/scores/invisible") == -50 && - purple_prefs_get_int("/purple/status/scores/away") == -100 && - purple_prefs_get_int("/purple/status/scores/extended_away") == -200 && - purple_prefs_get_int("/purple/status/scores/idle") == -400) - { - purple_prefs_set_int("/purple/status/scores/idle", -10); - } - return TRUE; }
--- a/libpurple/protocols/jabber/auth.c Tue Dec 25 22:59:15 2007 +0000 +++ b/libpurple/protocols/jabber/auth.c Tue Dec 25 23:00:27 2007 +0000 @@ -396,6 +396,24 @@ g_free(enc_out); } } + + if (mech && (strcmp(mech, "DIGEST-MD5") == 0)) { + /* CYRUS-SASL's DIGEST-MD5 and Java's DIGEST-MD5 are mutually incompatible because of different interpretations of RFC2831. + * This means that if we are using SASL and connecting to a Java-based server such as OpenFire, we will receive an authentication + * failure if that server offers DIGEST-MD5 in such a way that SASL chooses it as the best mechanism for us. + * + * However, we implement our own DIGEST-MD5 for use when we're compiled without SASL support, and that implementation + * works correctly. Therefore, if SASL chooses DIGEST-MD5, we switch over to our own implementation. + * jabber_auth_handle_challenge() will note the auth_type and take it from there. + * + * SASL would change state to SASL_OK after when handling the challenge; we do so immediately to avoid an error later. + */ + js->auth_type = JABBER_AUTH_DIGEST_MD5; + js->sasl_state = SASL_OK; + sasl_dispose(&js->sasl); + js->sasl = NULL; + } + jabber_send(js, auth); xmlnode_free(auth); } else { @@ -691,7 +709,7 @@ int i; challenge = xmlnode_get_attrib(xmlnode_get_child(query, "crammd5"), "challenge"); - auth_hmac_md5(challenge, strlen(challenge), pw, strlen(pw), &digest); + auth_hmac_md5(challenge, strlen(challenge), pw, strlen(pw), digest); /* Create the response query */ iq = jabber_iq_new_query(js, JABBER_IQ_SET, "jabber:iq:auth");
--- a/pidgin/gtkblist.c Tue Dec 25 22:59:15 2007 +0000 +++ b/pidgin/gtkblist.c Tue Dec 25 23:00:27 2007 +0000 @@ -409,6 +409,7 @@ static void gtk_blist_renderer_editing_cancelled_cb(GtkCellRenderer *renderer, PurpleBuddyList *list) { editing_blist = FALSE; + g_object_set(G_OBJECT(renderer), "editable", FALSE, NULL); pidgin_blist_refresh(list); } @@ -534,12 +535,14 @@ if (node_alias && !g_utf8_collate(node_alias, a)) { merges = g_list_append(merges, buddy); i++; + g_free(node_alias); + break; } g_free(node_alias); } } g_free(a); - + if (i > 1) { char *msg = g_strdup_printf(ngettext("You have %d contact named %s. Would you like to merge them?", "You currently have %d contacts named %s. Would you like to merge them?", i), i, alias); @@ -2575,28 +2578,37 @@ static struct tooltip_data * create_tip_for_node(PurpleBlistNode *node, gboolean full) { - char *tooltip_text = NULL; struct tooltip_data *td = g_new0(struct tooltip_data, 1); PurpleAccount *account = NULL; - char *tmp, *node_name; - - if(PURPLE_BLIST_NODE_IS_BUDDY(node)) { + char *tmp = NULL, *node_name = NULL, *tooltip_text = NULL; + + if (PURPLE_BLIST_NODE_IS_BUDDY(node)) { account = ((PurpleBuddy*)(node))->account; - } else if(PURPLE_BLIST_NODE_IS_CHAT(node)) { + } else if (PURPLE_BLIST_NODE_IS_CHAT(node)) { account = ((PurpleChat*)(node))->account; } td->status_icon = pidgin_blist_get_status_icon(node, PIDGIN_STATUS_ICON_LARGE); td->avatar = pidgin_blist_get_buddy_icon(node, !full, FALSE); - td->prpl_icon = pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_SMALL); + if (account != NULL) { + td->prpl_icon = pidgin_create_prpl_icon(account, PIDGIN_PRPL_ICON_SMALL); + } tooltip_text = pidgin_get_tooltip_text(node, full); td->layout = gtk_widget_create_pango_layout(gtkblist->tipwindow, NULL); td->name_layout = gtk_widget_create_pango_layout(gtkblist->tipwindow, NULL); - if (PURPLE_BLIST_NODE_IS_BUDDY(node)) + if (PURPLE_BLIST_NODE_IS_BUDDY(node)) { tmp = g_markup_escape_text(purple_buddy_get_name((PurpleBuddy*)node), -1); - else + } else if (PURPLE_BLIST_NODE_IS_CHAT(node)) { tmp = g_markup_escape_text(purple_chat_get_name((PurpleChat*)node), -1); + } else if (PURPLE_BLIST_NODE_IS_GROUP(node)) { + tmp = g_markup_escape_text(purple_group_get_name((PurpleGroup*)node), -1); + } else { + /* I don't believe this can happen currently, I think + * everything that calls this function checks for one of the + * above node types first. */ + tmp = g_strdup(_("Unknown node type")); + } node_name = g_strdup_printf("<span size='x-large' weight='bold'>%s</span>", tmp); g_free(tmp); @@ -2687,14 +2699,15 @@ } #if GTK_CHECK_VERSION(2,2,0) - if (dir == GTK_TEXT_DIR_RTL) - gdk_draw_pixbuf(GDK_DRAWABLE(gtkblist->tipwindow->window), NULL, td->status_icon, - 0, 0, max_width - TOOLTIP_BORDER - STATUS_SIZE, current_height, -1, -1, GDK_RGB_DITHER_NONE, 0, 0); - else - gdk_draw_pixbuf(GDK_DRAWABLE(gtkblist->tipwindow->window), NULL, td->status_icon, - 0, 0, TOOLTIP_BORDER, current_height, -1 , -1, GDK_RGB_DITHER_NONE, 0, 0); - if(td->avatar) - { + if (td->status_icon) { + if (dir == GTK_TEXT_DIR_RTL) + gdk_draw_pixbuf(GDK_DRAWABLE(gtkblist->tipwindow->window), NULL, td->status_icon, + 0, 0, max_width - TOOLTIP_BORDER - STATUS_SIZE, current_height, -1, -1, GDK_RGB_DITHER_NONE, 0, 0); + else + gdk_draw_pixbuf(GDK_DRAWABLE(gtkblist->tipwindow->window), NULL, td->status_icon, + 0, 0, TOOLTIP_BORDER, current_height, -1 , -1, GDK_RGB_DITHER_NONE, 0, 0); + } + if(td->avatar) { if (dir == GTK_TEXT_DIR_RTL) gdk_draw_pixbuf(GDK_DRAWABLE(gtkblist->tipwindow->window), NULL, td->avatar, 0, 0, TOOLTIP_BORDER, current_height, -1, -1, GDK_RGB_DITHER_NONE, 0, 0); @@ -2712,7 +2725,9 @@ -1 , -1, GDK_RGB_DITHER_NONE, 0, 0); #else - gdk_pixbuf_render_to_drawable(td->status_icon, GDK_DRAWABLE(gtkblist->tipwindow->window), NULL, 0, 0, 12, current_height, -1, -1, GDK_RGB_DITHER_NONE, 0, 0); + if (td->status_icon) { + gdk_pixbuf_render_to_drawable(td->status_icon, GDK_DRAWABLE(gtkblist->tipwindow->window), NULL, 0, 0, 12, current_height, -1, -1, GDK_RGB_DITHER_NONE, 0, 0); + } if(td->avatar) gdk_pixbuf_render_to_drawable(td->avatar, GDK_DRAWABLE(gtkblist->tipwindow->window), NULL, 0, 0, @@ -2778,7 +2793,9 @@ int width, height; gtkblist->tipwindow = widget; - if(PURPLE_BLIST_NODE_IS_CHAT(node) || PURPLE_BLIST_NODE_IS_BUDDY(node)) { + if(PURPLE_BLIST_NODE_IS_CHAT(node) || + PURPLE_BLIST_NODE_IS_BUDDY(node) || + PURPLE_BLIST_NODE_IS_GROUP(node)) { struct tooltip_data *td = create_tip_for_node(node, TRUE); gtkblist->tooltipdata = g_list_append(gtkblist->tooltipdata, td); width = TOOLTIP_BORDER + STATUS_SIZE + SMALL_SPACE + @@ -3271,10 +3288,44 @@ g_free(tmp); purple_notify_user_info_destroy(user_info); - } - - purple_signal_emit(pidgin_blist_get_handle(), - "drawing-tooltip", node, str, full); + } else if (PURPLE_BLIST_NODE_IS_GROUP(node)) { + GSList *accounts; + PurpleGroup *group = (PurpleGroup*)node; + PurpleNotifyUserInfo *user_info; + + user_info = purple_notify_user_info_new(); + + /* Total buddies (from online accounts) in group */ + tmp = g_strdup_printf("%d", + purple_blist_get_group_size(group, FALSE)); + purple_notify_user_info_add_pair(user_info, _("Total Buddies"), + tmp); + g_free(tmp); + + /* Online buddies in group */ + tmp = g_strdup_printf("%d", + purple_blist_get_group_online_count(group)); + purple_notify_user_info_add_pair(user_info, _("Online Buddies"), + tmp); + g_free(tmp); + + /* Accounts with buddies in group */ + accounts = purple_group_get_accounts(group); + for (; accounts != NULL; + accounts = g_slist_delete_link(accounts, accounts)) { + PurpleAccount *account = accounts->data; + purple_notify_user_info_add_pair(user_info, _("Account"), purple_account_get_username(account)); + } + + tmp = purple_notify_user_info_get_text_with_newline(user_info, "\n"); + g_string_append(str, tmp); + g_free(tmp); + + purple_notify_user_info_destroy(user_info); + } + + purple_signal_emit(pidgin_blist_get_handle(), "drawing-tooltip", + node, str, full); return g_string_free(str, FALSE); }
--- a/pidgin/minidialog.c Tue Dec 25 22:59:15 2007 +0000 +++ b/pidgin/minidialog.c Tue Dec 25 23:00:27 2007 +0000 @@ -63,6 +63,7 @@ sizeof (PidginMiniDialog), 0, /* n_preallocs */ (GInstanceInitFunc) pidgin_mini_dialog_init, + NULL, }; g_define_type_id = g_type_register_static (GTK_TYPE_VBOX, "PidginMiniDialog", &g_define_type_info, 0);
--- a/pidgin/pidgincombobox.c Tue Dec 25 22:59:15 2007 +0000 +++ b/pidgin/pidgincombobox.c Tue Dec 25 23:00:27 2007 +0000 @@ -2980,7 +2980,7 @@ g_return_if_fail (link != NULL); - combo_box->priv->cells = g_slist_remove_link (combo_box->priv->cells, link); + combo_box->priv->cells = g_slist_delete_link (combo_box->priv->cells, link); combo_box->priv->cells = g_slist_insert (combo_box->priv->cells, info, position);
--- a/pidgin/win32/nsis/pidgin-installer.nsi Tue Dec 25 22:59:15 2007 +0000 +++ b/pidgin/win32/nsis/pidgin-installer.nsi Tue Dec 25 23:00:27 2007 +0000 @@ -699,6 +699,7 @@ Delete "$INSTDIR\ca-certs\Equifax_Secure_CA.pem" Delete "$INSTDIR\ca-certs\GTE_CyberTrust_Global_Root.pem" Delete "$INSTDIR\ca-certs\Microsoft_Secure_Server_Authority.pem" + Delete "$INSTDIR\ca-certs\StartCom_Free_SSL_CA.pem" Delete "$INSTDIR\ca-certs\Verisign_Class3_Extended_Validation_CA.pem" Delete "$INSTDIR\ca-certs\Verisign_Class3_Primary_CA.pem" Delete "$INSTDIR\ca-certs\Verisign_RSA_Secure_Server_CA.pem"
--- a/share/ca-certs/Makefile.am Tue Dec 25 22:59:15 2007 +0000 +++ b/share/ca-certs/Makefile.am Tue Dec 25 23:00:27 2007 +0000 @@ -3,6 +3,7 @@ Equifax_Secure_CA.pem \ GTE_CyberTrust_Global_Root.pem \ Microsoft_Secure_Server_Authority.pem \ + StartCom_Free_SSL_CA.pem \ Verisign_RSA_Secure_Server_CA.pem \ Verisign_Class3_Primary_CA.pem
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/share/ca-certs/StartCom_Free_SSL_CA.pem Tue Dec 25 23:00:27 2007 +0000 @@ -0,0 +1,30 @@ +-----BEGIN CERTIFICATE----- +MIIFFjCCBH+gAwIBAgIBADANBgkqhkiG9w0BAQQFADCBsDELMAkGA1UEBhMCSUwx +DzANBgNVBAgTBklzcmFlbDEOMAwGA1UEBxMFRWlsYXQxFjAUBgNVBAoTDVN0YXJ0 +Q29tIEx0ZC4xGjAYBgNVBAsTEUNBIEF1dGhvcml0eSBEZXAuMSkwJwYDVQQDEyBG +cmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJARYS +YWRtaW5Ac3RhcnRjb20ub3JnMB4XDTA1MDMxNzE3Mzc0OFoXDTM1MDMxMDE3Mzc0 +OFowgbAxCzAJBgNVBAYTAklMMQ8wDQYDVQQIEwZJc3JhZWwxDjAMBgNVBAcTBUVp +bGF0MRYwFAYDVQQKEw1TdGFydENvbSBMdGQuMRowGAYDVQQLExFDQSBBdXRob3Jp +dHkgRGVwLjEpMCcGA1UEAxMgRnJlZSBTU0wgQ2VydGlmaWNhdGlvbiBBdXRob3Jp +dHkxITAfBgkqhkiG9w0BCQEWEmFkbWluQHN0YXJ0Y29tLm9yZzCBnzANBgkqhkiG +9w0BAQEFAAOBjQAwgYkCgYEA7YRgACOeyEpRKSfeOqE5tWmrCbIvNP1h3D3TsM+x +18LEwrHkllbEvqoUDufMOlDIOmKdw6OsWXuO7lUaHEe+o5c5s7XvIywI6Nivcy+5 +yYPo7QAPyHWlLzRMGOh2iCNJitu27Wjaw7ViKUylS7eYtAkUEKD4/mJ2IhULpNYI +LzUCAwEAAaOCAjwwggI4MA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgHmMB0G +A1UdDgQWBBQcicOWzL3+MtUNjIExtpidjShkjTCB3QYDVR0jBIHVMIHSgBQcicOW +zL3+MtUNjIExtpidjShkjaGBtqSBszCBsDELMAkGA1UEBhMCSUwxDzANBgNVBAgT +BklzcmFlbDEOMAwGA1UEBxMFRWlsYXQxFjAUBgNVBAoTDVN0YXJ0Q29tIEx0ZC4x +GjAYBgNVBAsTEUNBIEF1dGhvcml0eSBEZXAuMSkwJwYDVQQDEyBGcmVlIFNTTCBD +ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJARYSYWRtaW5Ac3Rh +cnRjb20ub3JnggEAMB0GA1UdEQQWMBSBEmFkbWluQHN0YXJ0Y29tLm9yZzAdBgNV +HRIEFjAUgRJhZG1pbkBzdGFydGNvbS5vcmcwEQYJYIZIAYb4QgEBBAQDAgAHMC8G +CWCGSAGG+EIBDQQiFiBGcmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAy +BglghkgBhvhCAQQEJRYjaHR0cDovL2NlcnQuc3RhcnRjb20ub3JnL2NhLWNybC5j +cmwwKAYJYIZIAYb4QgECBBsWGWh0dHA6Ly9jZXJ0LnN0YXJ0Y29tLm9yZy8wOQYJ +YIZIAYb4QgEIBCwWKmh0dHA6Ly9jZXJ0LnN0YXJ0Y29tLm9yZy9pbmRleC5waHA/ +YXBwPTExMTANBgkqhkiG9w0BAQQFAAOBgQBscSXhnjSRIe/bbL0BCFaPiNhBOlP1 +ct8nV0t2hPdopP7rPwl+KLhX6h/BquL/lp9JmeaylXOWxkjHXo0Hclb4g4+fd68p +00UOpO6wNnQt8M2YI3s3S9r+UZjEHjQ8iP2ZO1CnwYszx8JSFhKVU2Ui77qLzmLb +cCOxgN8aIDjnfg== +-----END CERTIFICATE-----