/// <summary>
        /// Entry point of registration processing, called by static DoCall() of base class.
        /// Builds XML, generates SharedSecret, calls ContextWS register() method and updates database upon success.
        /// </summary>
        public override void Call()
        {
            log4net.ILog log  = PtaUtil.getLog4netLogger(typeof(RegisterToolWSCall).FullName + ".Call(): ");
            String       desc = GetRegistrationXML(wsWrapper.GetBBHostCode());

            if (!IsReregister)
            {
                initialSharedSecret = System.Guid.NewGuid().ToString();
                initialSharedSecret = Regex.Replace(initialSharedSecret, "-", "");
                initialSharedSecret = Regex.Replace(initialSharedSecret, ":", "_");
            }
            else
            {
                initialSharedSecret = PtaUtil.GetDBReaderStringField(wsWrapper.GetBBoardDR(), "SharedSecret");
            }


            RegisterToolResultVO res;

            string[] requiredToolMethods   = null;
            string[] requiredTicketMethods = null;
            //commented for security reasons
            //log.Debug("toolRegistrationPassword: "******"desc: " + desc);
            //commented for security reasons
            //log.Debug("initialSharedSecret: " + initialSharedSecret);
            String proxy_code = PtaUtil.GetDBReaderStringField(wsWrapper.GetBBoardDR(), "BBoardProxyCode");

            res = wsWrapper.GetContextWS().registerTool("IDLA", proxy_code, toolRegistrationPassword, desc, initialSharedSecret, requiredToolMethods, requiredTicketMethods);
            String str = res.ToString();

            str = res.proxyToolGuid;
            if (res.status)
            {
                String sql = "UPDATE BBoard SET IsRegistered = @IsRegistered, SharedSecret = @SharedSecret, GUID = @GUID, ProxyState='Inactive'  WHERE BBoardCode = @BBoardCode";
                log.Info("sql: " + sql);
                SqlParameter[] update_bb_params = new SqlParameter[] {
                    new SqlParameter("@IsRegistered", "Y"),
                    new SqlParameter("@SharedSecret", initialSharedSecret),
                    new SqlParameter("@GUID", res.proxyToolGuid),
                    new SqlParameter("@BBoardCode", wsWrapper.GetBBHostCode())
                };
                log.Info("res.proxyToolGuid: " + res.proxyToolGuid);
                log.Info("ws_wrapper.bbHostCode: " + wsWrapper.GetBBHostCode());
                Microsoft.ApplicationBlocks.Data.SqlHelper.ExecuteNonQuery(PtaUtil.GetSqlConnection(),
                                                                           System.Data.CommandType.Text, sql, update_bb_params);
            }
            else
            {
                String failure_errors = "";
                for (int i = 0; i < res.failureErrors.Count(); i++)
                {
                    failure_errors += "BB Falire Err.#" + i + ": " + res.failureErrors[i] + ";\r\n ";
                }
                throw new PtaRegisterToolException(wsWrapper.GetContextWS().GetType().FullName + ".registerTool() failed with following error(s): \r\n " + failure_errors, res);
            }
        }
Пример #2
0
        /// <summary>
        /// Initializes communication channel with Blackboard.
        /// Depending on BBoard.BBoardHTTPSchema DB setting first tries to establish https
        /// and in case of fail - http one. Or makes single attempt on one of them if restricted to such behavior.
        /// </summary>
        public void initialize()
        {
            log4net.ILog log            = PtaUtil.getLog4netLogger(this.GetType().FullName + ".initialize(): ");
            String       url_prefix     = "http://";
            Int16        port_num       = PtaUtil.GetDBReaderInt16Field(bboardDR, "BBoardHTTPPort");
            String       bb_http_schema = "";

            try {
                bb_http_schema = PtaUtil.GetDBReaderStringField(bboardDR, "BBoardHTTPSchema");
                log.Debug("bb_http_schema: " + bb_http_schema);
                if ("HTTPS".Equals(bb_http_schema) ||
                    "BOTH".Equals(bb_http_schema)
                    )
                {
                    url_prefix = "https://";
                    port_num   = PtaUtil.GetDBReaderInt16Field(bboardDR, "BBoardHTTPSPort");
                }
                else if (!"HTTP".Equals(bb_http_schema))
                {
                    throw new PtaException("BBoardHTTPSchema has to contain either HTTP, HTTPS or BOTH.");
                }
                contextWS.Url = url_prefix + GetBBHostURL() + ":" + port_num.ToString() + "/webapps/ws/services" + "/Context.WS";
                initializeInternal();
            } catch (System.Net.WebException we) {
                //checking of message text looks to be too strong condition
                //When certificate is incorrect message is "The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel."
                //When certificate is incorrect message is "The underlying connection was closed: An unexpected error occurred on a send" and inner exception "Authentication failed because the remote party has closed the transport stream."
                //if (we.Message.Equals("The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.")
                log.Warn(we);
                if ("BOTH".Equals(bb_http_schema))
                {
                    port_num      = PtaUtil.GetDBReaderInt16Field(bboardDR, "BBoardHTTPPort");
                    contextWS.Url = "http://" + GetBBHostURL() + ":" + port_num.ToString() + "/webapps/ws/services" + "/Context.WS";
                    initializeInternal();
                }
                else
                {
                    throw;
                }
            }
        }
        /// <summary>
        /// Standard entry point of IHttpHandler, main processing flow.
        /// </summary>
        public void ProcessRequest(HttpContext context)
        {
            log4net.ILog log = PtaUtil.getLog4netLogger(this.GetType().FullName + ".ProcessRequest(): ");
            try {
                this.context = context;
                String guid = context.Request.Form["ourguid"];
                bboardDR = PtaUtil.GetBBoardDataReaderByGuid(guid);
                onErrorServerTransfer = PtaUtil.GetDBReaderStringField(bboardDR, "OnErrorServerTransfer");
                RequestValidator rv = new RequestValidator(bboardDR);
                rv.Validate(context.Request);
                Redirect();
            } catch (System.Threading.ThreadAbortException) {
                //this is normal processing of Server.Transfer() and Response.End()
                throw;
            } catch (Exception e) {
                PtaUtil.LogExceptionAndFormParameters(log, e);
                //String on_err_st = onErrorServerTransfer;
                //if (on_err_st == null) on_err_st = PtaUtil.GetProxyWebFolder() + "ErrorPages/PtaDefaultErrPage.aspx";
                //context.Server.Transfer(on_err_st, true);
                String back_link = context.Request.Form["tcbaseurl"] + context.Request.Form["returnurl"];
                String err_page  = PtaUtil.GenerateSimpleErrorPage(back_link);
                context.Response.Write(err_page);
                log.Debug("onErrorServerTransfer: " + onErrorServerTransfer);
                if (onErrorServerTransfer != null)
                {
                    context.Server.Transfer(onErrorServerTransfer, true);
                }

                /*                else {
                 *                  back_link = context.Request.Form["tcbaseurl"] + context.Request.Form["returnurl"];
                 *                  context.Response.Write("Your request could not be processed. <br/>");
                 *                  context.Response.Write("Back to Blackboard: " + "<a href=\"" + back_link + "\">" + back_link + "</a><br/>");
                 *              }*/

                //throw;
            } finally {
                PtaUtil.CloseDataReader(drParam);
                PtaUtil.CloseDataReader(drMenuLink);
                PtaUtil.CloseDataReader(bboardDR);
            }
        }
Пример #4
0
 private String GetBBHostURL()
 {
     return(PtaUtil.GetDBReaderStringField(bboardDR, "BBoardURL"));
 }
Пример #5
0
 public String GetBBHostCode()
 {
     return(PtaUtil.GetDBReaderStringField(bboardDR, "BBoardCode"));
 }
Пример #6
0
        /// <summary>
        /// Performs series of actions necessary for validation of passed by Blackboard parameters.
        /// See http://www.edugarage.com/display/BBDN/Proxy+Tool+SSO , internal method comments and java client sample code for details.
        /// Performs periodical cleanup of collected nonces upon every NonceCleanupCount invocation
        /// </summary>
        public void Validate(HttpRequest request)
        {
            log4net.ILog log = PtaUtil.getLog4netLogger(this.GetType().FullName + ".Validate(): ");
            request.ContentEncoding = System.Text.Encoding.UTF8;


            if (bboardDR == null)
            {
                bboardDR = PtaUtil.GetBBoardDataReaderByGuid(guid);
            }

            String s_secret = PtaUtil.GetDBReaderStringField(bboardDR, "SharedSecret");

            //http://www.edugarage.com/display/BBDN/Proxy+Tool+SSO
            // 1. Sort the posted data based on the key names and then concatenate all of the values together in the sorted order
            String[] sorted_form_keys = request.Form.AllKeys;
            Array.Sort(sorted_form_keys);
            System.Text.StringBuilder data_string = new System.Text.StringBuilder("");
            foreach (String form_key in sorted_form_keys)
            {
                /* from proxy\java\src\com\blackboard\test\proxy\GenericParameters.java:
                 * // ignore extra parameters added after the mac was generated/set
                 *  if ( key.startsWith( "top_" ) || key.startsWith( "bottom_" ) )
                 *      {
                 *          //ignore
                 *      }
                 * */
                if (form_key.StartsWith("top_", StringComparison.OrdinalIgnoreCase) ||
                    form_key.StartsWith("bottom_", StringComparison.OrdinalIgnoreCase)
                    //MAC cannot be calculated over itself
                    || form_key.Equals("mac", StringComparison.OrdinalIgnoreCase))
                {
                    continue;
                }
                data_string.Append(request.Form[form_key]);
            }
            log.Debug("data_string: " + data_string);
            // 2. append the shared secret
            data_string.Append(s_secret);
            // 3. Turn this string into a string of utf-8 bytes
            byte[] data_buffer = System.Text.Encoding.UTF8.GetBytes(data_string.ToString());
            // 4. Create a message digest from these bytes
            System.Security.Cryptography.MD5 md = new System.Security.Cryptography.MD5CryptoServiceProvider();
            byte[] md5_hash = md.ComputeHash(data_buffer);
            // 5. Convert the resulting byte array into a base64 encoded string
            String md5_hash_64 = System.Convert.ToBase64String(md5_hash);

            log.Debug("md5_hash_64: " + md5_hash_64);
            //relace operations below are copied from proxy\java\src\com\blackboard\test\proxy\ProxyUtil.java  generateMac()
            md5_hash_64.Replace("\r", "");
            md5_hash_64.Replace("\n", "");
            log.Debug("md5_hash_64: " + md5_hash_64);

            String bb_mac = request.Form[PtaServerConstants.MAC_KEY];

            log.Debug("bb_mac: " + bb_mac);

            //compare received and calculated MACs
            if (!bb_mac.Equals(md5_hash_64))
            {
                throw new PtaException("MAC mismatch. md5_hash_64: " + md5_hash_64 + "; bb_mac: " + bb_mac);
            }

            //check that timestamp is expected timeframe
            String bb_ts     = request.Form[PtaServerConstants.TIMESTAMP_KEY];
            long   bb_millis = Int64.Parse(bb_ts);

            log.Debug("bb_millis: " + bb_millis);

            long mac_life_ms = Int64.Parse(WebConfigurationManager.AppSettings["MacLifetimeInMinutes"]);

            log.Debug("mac_life_ms: " + mac_life_ms);
            long mac_life_millis = mac_life_ms * 1000 * 60;

            //http://bytes.com/topic/c-sharp/answers/557734-java-system-currenttimemillis-equivalent
            //- about java System.currentTimeMillis() in .net
            DateTime utc_now = DateTime.UtcNow;

            log.Debug("utc_now: " + utc_now);
            DateTime base_time = new DateTime(1970, 1, 1, 0, 0, 0);

            log.Debug("base_time: " + base_time);
            long proxy_millis = (utc_now - base_time).Ticks / 10000;

            log.Debug("proxy_millis: " + proxy_millis);

            if (Math.Abs(proxy_millis - bb_millis) > mac_life_millis)   //added abs() - not to be much earlier too. Assuming that earlier timestamp may be possible due to non-synchronized system time on BB and proxy server
            {
                throw new PtaException("Timestamp is out of max request delay. proxy_millis(secs): " + proxy_millis + "(" + proxy_millis / 1000 + "); bb_millis(secs): " + bb_millis + "(" + bb_millis / 1000 + "); mac_life_ms(secs): " + mac_life_millis + "(" + mac_life_millis / 1000 + ")");
            }

            String nonce = request.Form[PtaServerConstants.NONCE_KEY];

            if (nonce == null)
            {
                throw new PtaException("Invalid null Nonce");
            }
            if (RequestValidator.knownNonces.Contains(nonce))
            {
                throw new PtaException("Invalid duplicated Nonce. nonce: " + nonce);
            }
            int nonce_cleanup_count = Int16.Parse(WebConfigurationManager.AppSettings["NonceCleanupCount"]);

            lock (typeof(RequestValidator)) {
                knownNonces.Add(nonce, proxy_millis);
                nonceCleanupCounter++;

                if (nonceCleanupCounter > nonce_cleanup_count)
                {
                    //!! test/debug
                    Hashtable non_expired_nonces = new Hashtable();
                    foreach (DictionaryEntry nonce_de in RequestValidator.knownNonces)
                    {
                        long nonce_millis = (long)nonce_de.Value;
                        if (nonce_millis >= proxy_millis - mac_life_millis)
                        {
                            non_expired_nonces.Add(nonce_de.Key, nonce_millis);
                        }
                    }
                    knownNonces         = non_expired_nonces;
                    nonceCleanupCounter = 0;
                }
            }
        }
        /// <summary>
        /// Implements redirection logic.
        /// Please see "V. Link redirection processing definition" in pta_proxy\readme.txt for description of processing.
        /// Parameters provided by Blackboard along with redirection link are described at
        /// http://www.edugarage.com/display/BBDN/Generic+Proxy+Tool+Request+Arguments
        /// Link types at
        /// http://www.edugarage.com/display/BBDN/Link+Type
        /// Response status codes and header fields:
        /// http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html#sec6
        /// http://grokable.com/understanding-asp-net-response-redirect/ 301 vs. 302: Response.Redirect sets an HTTP 302 header along with the URL to be redirected to. The 302 status code essentially says, "this item has moved temporarily". Search engines crawling your site are not guaranteed to follow 302 redirects, nor should they. By following a 302 the search engine could incorrectly index the location of content.
        /// Response.Redirect with POST instead of Get?
        /// http://stackoverflow.com/questions/46582/response-redirect-with-post-instead-of-get
        /// </summary>
        protected void Redirect()
        {
            log4net.ILog log              = PtaUtil.getLog4netLogger(this.GetType().FullName + ".Redirect(): ");
            String       bb_code          = PtaUtil.GetDBReaderStringField(bboardDR, "BBoardCode");
            String       proxy_web_folder = PtaUtil.GetProxyWebFolder();
            String       bb_link          = context.Request.Path.Replace(proxy_web_folder + PtaUtil.PTA_SUBFOLDER, "");

            log.Debug("bb_code: " + bb_code + "; proxy_web_folder: " + proxy_web_folder + "; bb_link: " + bb_link);

            System.Data.SqlClient.SqlConnection con = PtaUtil.GetSqlConnection();
            String sql = "SELECT BBLinkType FROM BBMenuLink WHERE BBoardCode = @BBoardCode AND BBLinkPath = @BBLinkPath";

            System.Data.SqlClient.SqlParameter[] sel_ml_params = new System.Data.SqlClient.SqlParameter[] {
                new System.Data.SqlClient.SqlParameter("@BBoardCode", bb_code),
                new System.Data.SqlClient.SqlParameter("@BBLinkPath", bb_link)
            };
            log.Info("sql: " + sql);
            drMenuLink = Microsoft.ApplicationBlocks.Data.SqlHelper.ExecuteReader(PtaUtil.GetSqlConnection(),
                                                                                  System.Data.CommandType.Text, sql, sel_ml_params);
            if (!drMenuLink.HasRows)
            {
                throw new PtaException("Unknown proxy link. " + "bb_code: " + bb_code + "; proxy_web_folder: " + proxy_web_folder + "; bb_link: " + bb_link);
            }
            drMenuLink.Read();

            sql  = "SELECT ParamTag, ParamOrderCode, ParamKey, ParamInputType, ParamOutputType, ParamInputTemplate, ";
            sql += "RegExp, RegExpOperation, RegExpReplaceString, RegExpMatchGroup, RegExpMatchCapture, SProcName ";
            sql += "FROM Param WHERE BBoardCode = @BBoardCode AND BBLinkPath = @BBLinkPath ORDER BY ParamOrderCode";
            log.Info("sql: " + sql);
            System.Data.SqlClient.SqlDataReader drParam =
                Microsoft.ApplicationBlocks.Data.SqlHelper.ExecuteReader(PtaUtil.GetSqlConnection(),
                                                                         System.Data.CommandType.Text, sql, sel_ml_params);
            if (!drParam.HasRows)
            {
                throw new PtaException("No defined link parameter transformations. " + "bb_code: " + bb_code + "; proxy_web_folder: " + proxy_web_folder + "; bb_link: " + bb_link);
            }

            System.Collections.Hashtable param_tags_hash = new System.Collections.Hashtable();
            while (drParam.Read())
            {
                String param_tag    = PtaUtil.GetDBReaderStringField(drParam, "ParamTag");
                String param_input  = PtaUtil.GetDBReaderStringField(drParam, "ParamInputType");
                String param_output = PtaUtil.GetDBReaderStringField(drParam, "ParamOutputType");
                String input_templ  = PtaUtil.GetDBReaderStringField(drParam, "ParamInputTemplate");
                String param_key    = PtaUtil.GetDBReaderStringField(drParam, "ParamKey");
                String param_value  = null;
                log.Debug("param_tag: " + param_tag + "; param_input: " + param_input + "; param_output: " + param_output + "; input_templ: " + input_templ + "; param_key: " + param_key);
                switch (param_input)
                {
                case "Param.InputTemplate":
                    MatchCollection mc = Regex.Matches(input_templ, "{[^}]*}");
                    foreach (Match match in mc)
                    {
                        GroupCollection groups = match.Groups;
                        foreach (Group grp in groups)
                        {
                            String tag       = grp.Value;
                            String tag_value = (string)param_tags_hash[tag];
                            input_templ = Regex.Replace(input_templ, tag, tag_value);
                            log.Debug("tag: " + tag + "; tag_value: " + tag_value + "; input_templ: " + input_templ);
                        }
                    }
                    param_value = input_templ;
                    break;

                case "ProxyLinkPath":
                    param_value = bb_link;
                    break;

                case "ProxyLinkType":
                    param_value = PtaUtil.GetDBReaderStringField(drMenuLink, "BBLinkType");
                    break;

                case "ProxyPath":
                    param_value = proxy_web_folder;
                    break;

                case "Request.ApplicationPath":
                    param_value = context.Request.ApplicationPath;
                    if (param_value.Equals("/"))
                    {
                        param_value = "";
                    }
                    break;

                case "Request.FilePath":
                    param_value = context.Request.FilePath;
                    break;

                case "Request.Form":
                    param_value = context.Request.Form[param_key];
                    break;

                case "Request.InputStream":
                    System.IO.StreamReader reader = new System.IO.StreamReader(context.Request.InputStream);
                    param_value = reader.ReadToEnd();
                    break;

                case "Request.QueryString":
                    throw new PtaException("ParamInputType=Request.QueryString is not implemented. Supplied URL query string parameters are ignored and cut off by Blackboard.");

                case "Request.PathInfo":
                    param_value = context.Request.PathInfo;
                    break;

                case "Request.Url.ToString":
                    log.Debug("Request.Url.AbsolutePath(): " + context.Request.Url.AbsolutePath + "; context.Request.Url.ToString(): " + context.Request.Url.ToString());
                    param_value = context.Request.Url.ToString();
                    break;

                case "SProcCall":
                    //defined this way list provides correct conversion psp_params.ToArray() accepted by SqlHelper.ExecuteNonQuery()
                    System.Collections.Generic.List <System.Data.SqlClient.SqlParameter> psp_params =
                        new System.Collections.Generic.List <System.Data.SqlClient.SqlParameter>();

                    MatchCollection mc1 = Regex.Matches(input_templ, "{[^}]*}");
                    foreach (Match match in mc1)
                    {
                        GroupCollection groups = match.Groups;
                        foreach (Group grp in groups)
                        {
                            String tag       = grp.Value;
                            String tag_value = (string)param_tags_hash[tag];
                            tag = tag.Replace("{", "").Replace("}", "");
                            log.Debug("tag: " + tag + "; tag_value: " + tag_value);
                            psp_params.Add(new System.Data.SqlClient.SqlParameter("@" + tag, tag_value));
                        }
                    }
                    String sp_out_param_name = param_key;
                    System.Data.SqlClient.SqlParameter out_param = null;
                    if (sp_out_param_name != null)
                    {
                        out_param = //had problems with getting of output value, required ParameterDirection - this is why called constructor is so complex
                                    //Initializes a new instance of the SqlParameter class that uses the parameter name, the type of the parameter, the size of the parameter, a ParameterDirection, the precision of the parameter, the scale of the parameter, the source column, a DataRowVersion to use, and the value of the parameter.
                                    new System.Data.SqlClient.SqlParameter("@" + sp_out_param_name, SqlDbType.NVarChar,
                                                                           255, ParameterDirection.InputOutput, true, 0, 0, null,
                                                                           DataRowVersion.Current, "");
                        log.Debug("sp_out_param_name: " + sp_out_param_name);
                        psp_params.Add(out_param);
                    }
                    String sproc_name = PtaUtil.GetDBReaderStringField(drParam, "SProcName");
                    log.Debug("sproc_name: " + sproc_name);
                    if (psp_params.Count > 0)
                    {
                        Microsoft.ApplicationBlocks.Data.SqlHelper.ExecuteNonQuery(con, CommandType.StoredProcedure, sproc_name, psp_params.ToArray());
                    }
                    else
                    {
                        Microsoft.ApplicationBlocks.Data.SqlHelper.ExecuteNonQuery(con, CommandType.StoredProcedure, sproc_name);
                    }
                    if (out_param != null)
                    {
                        param_value = (string)out_param.Value;
                    }
                    break;

                case "BBWSCall":
                    throw new PtaException("ParamInputType=BBWSCall is not implemented at this time. It may provide possibility to get additional information from Blackboard via WS calls in future.");

                default:
                    throw new PtaException("ParamInputType=" + param_input + " is not implemented. Unknown, possible inconsistensy of code and ParamInputCheck DB constraint.");
                }
                log.Debug("param_value after input processing: " + param_value);

                String regexp_oper = PtaUtil.GetDBReaderStringField(drParam, "RegExpOperation");
                String regexp      = PtaUtil.GetDBReaderStringField(drParam, "RegExp");
                String regexp_rs   = PtaUtil.GetDBReaderStringField(drParam, "RegExpReplaceString");
                int    regexp_mc   = PtaUtil.GetDBReaderInt16Field(drParam, "RegExpMatchCapture");
                int    regexp_mg   = PtaUtil.GetDBReaderInt16Field(drParam, "RegExpMatchGroup");
                log.Debug("regexp_oper: " + regexp_oper + "; regexp: " + regexp + "; regexp_rs: " + regexp_rs + "; regexp_mc: " + regexp_mc + "; regexp_mg: " + regexp_mg);
                switch (regexp_oper)
                {
                case "Assign":
                    break;

                case "REMatch":
                    param_value = "";
                    MatchCollection mc3 = Regex.Matches(param_value, regexp);
                    log.Debug("mc3.Count: " + mc3.Count);
                    if (mc3.Count < regexp_mc)
                    {
                        Match m = mc3[regexp_mc];
                        log.Debug("m.Groups.Count: " + m.Groups.Count);
                        if (m.Groups.Count < regexp_mg)
                        {
                            param_value = m.Groups[regexp_mg].Value;
                        }
                    }
                    break;

                case "REReplace":
                    param_value = Regex.Replace(param_value, regexp, regexp_rs);
                    break;

                default:
                    throw new PtaException("RegExpOperation=" + regexp_oper + " is not implemented. Unknown, possible inconsistensy of code and RegExpOperationCheck DB constraint.");
                }
                log.Info("final param_tag: " + param_tag + "; param_value: " + param_value);
                param_tags_hash.Add(param_tag, param_value);

                switch (param_output)
                {
                case "None":
                    break;

                case "FormsAuthentication.SetAuthCookie":
                    System.Web.Security.FormsAuthentication.SetAuthCookie(param_value, false);
                    break;

                case "Context.Items":
                    context.Items[param_key] = param_value;
                    break;

                case "Context.Session":
                    context.Session.Add(param_key, param_value);
                    break;

                case "Response.AppendHeader":
                    context.Response.AppendHeader(param_key, param_value);
                    break;

                case "Response.Output":
                    context.Response.Output.Write(param_value);
                    break;

                case "Response.Status":
                    context.Response.Status = param_value;
                    break;

                case "Server.Transfer":
                    context.Server.Transfer(param_value, true);
                    break;

                default:
                    throw new PtaException("ParamOutputType=" + param_output + " is not implemented. Unknown, possible inconsistensy of code and ParamOutputCheck DB constraint.");
                }
            } //while (drParam.Read()) {
              //http://weblogs.asp.net/bleroy/archive/2004/08/03/Don_2700_t-redirect-after-setting-a-Session-variable-_2800_or-do-it-right_2900_.aspx
              //recommends use of Response.Redirect("~/default.aspx", false);
              //In comments:
              //I was lossing session data after clicking on a new page on a web site I was building only one of the pages out of about 25 was having this issue and it was always the same page.  As soon as I copied the page on to the IIS server on my computer the problem went away.  I think that something was going wrong on the server that visual web developer 2005 was running.

            //context.Response.End(); -- does not preserve session variables
            //finally ended with no specific processing here - everything seems fine this way.
            //probably enabling of Flush() should be tried first if something will stop working as required
            //context.Response.Flush();
        }
        /// <summary>
        /// Made as static for simplicity of registration XML preview (pta_proxy\Admin\Register.aspx).
        /// </summary>
        static public String GetRegistrationXML(String bbCode)
        {
            log4net.ILog log = PtaUtil.getLog4netLogger(typeof(RegisterToolWSCall).FullName + ".getRegistrationXML: ");
            String       desc;
            //method is static because can be called for preview, i.e. WSCall.wsWrapper.GetBBoardDR() is unavailvable
            SqlDataReader bboardDR = PtaUtil.GetBBoardDataReaderByCode(bbCode);

            try {
                if ("Y".Equals(PtaUtil.GetDBReaderStringField(bboardDR, "IsRegistered")))
                {
                    //??probably some logic on preliminary handling of this can be placed here,
                    //but capability to reregister even with this flag set is necessary
                    //because it is possible proxy to be unregistered at Blackboard but not updated at proxy
                    //(if proxy is not accessibel at the moment of unregistration),
                    //i.e. IsRegistered (as well as ProxyState) can be out of sync with Blackboard
                }
                String proxy_http_url  = WebConfigurationManager.AppSettings["PtaProxyHttpUrl"];
                String proxy_https_url = WebConfigurationManager.AppSettings["PtaProxyHttpsURL"];
                String proxy_s2s_url   = WebConfigurationManager.AppSettings["PtaProxyServerToServerURL"];
                String base_urls       = "";
                if ("Y".Equals(PtaUtil.GetDBReaderStringField(bboardDR, "RegisterHttpsURL")))
                {
                    base_urls += "<base-url type=\"https\">" + proxy_https_url + "</base-url>\n";
                }
                if ("Y".Equals(PtaUtil.GetDBReaderStringField(bboardDR, "RegisterHttpURL")))
                {
                    base_urls += "<base-url type=\"http\">" + proxy_http_url + "</base-url>\n";
                }
                if ("Y".Equals(PtaUtil.GetDBReaderStringField(bboardDR, "RegisterS2SURL")))
                {
                    base_urls += "<base-url type=\"server-to-server\">" + proxy_s2s_url + "</base-url>\n";
                }
                desc = Regex.Replace(REG_XML, "{BASE_URLS}", base_urls);
                if ("Y".Equals(PtaUtil.GetDBReaderStringField(bboardDR, "RegisterActions")))
                {
                    desc = Regex.Replace(desc, "{HTTP_ACTIONS}", HTTP_ACTIONS_XML);
                }
                String proxy_code = PtaUtil.GetDBReaderStringField(bboardDR, "BBoardProxyCode");
                desc = Regex.Replace(desc, "{PROXY_CODE}", proxy_code);


                //String desc = Regex.Replace(REG_XML, "{BASE_HTTP_URL}", proxy_http_url);
                //desc = Regex.Replace(desc, "{BASE_HTTPS_URL}", proxy_https_url);
                desc = Regex.Replace(desc, "{PROXY_WEB_FOLDER}", PtaUtil.GetProxyWebFolder());


                String sql = "SELECT BBLinkPath, BBLinkType, BBLinkName, BBLinkIconPath FROM BBMenuLink WHERE BBoardCode = @BBoardCode AND Enabled = 'Y'";
                log.Info("sql: " + sql);
                SqlConnection con = PtaUtil.GetSqlConnection();
                System.Data.SqlClient.SqlParameter param
                    = new System.Data.SqlClient.SqlParameter("BBoardCode", PtaUtil.GetDBReaderStringField(bboardDR, "BBoardCode"));
                SqlDataReader drMenuLink =
                    Microsoft.ApplicationBlocks.Data.SqlHelper.ExecuteReader(con, System.Data.CommandType.Text,
                                                                             sql, param);
                String xml_links = "";
                while (drMenuLink.Read())
                {
                    String xml_part  = MENU_LINK_XML;
                    String link_path = PtaUtil.GetProxyWebFolder() + PtaUtil.PTA_SUBFOLDER + PtaUtil.GetDBReaderStringField(drMenuLink, "BBLinkPath");
                    String link_type = PtaUtil.GetDBReaderStringField(drMenuLink, "BBLinkType");
                    String link_name = PtaUtil.GetDBReaderStringField(drMenuLink, "BBLinkName");
                    String icon_path = PtaUtil.GetDBReaderStringField(drMenuLink, "BBLinkIconPath");
                    xml_part = Regex.Replace(xml_part, "{LINK_PATH}", link_path);
                    xml_part = Regex.Replace(xml_part, "{MENU_LINK_TYPE}", link_type);
                    xml_part = Regex.Replace(xml_part, "{LINK_NAME}", "<name locale:key=\"" + link_name + "\"></name>");
                    if (icon_path != null)
                    {
                        xml_part = Regex.Replace(xml_part, "{LINK_ICON}", "<icon platform=\"blackboard\" style=\"listitem\" >" + icon_path + "</icon>");
                    }
                    else
                    {
                        xml_part = Regex.Replace(xml_part, "{LINK_ICON}", "");
                    }
                    xml_links = xml_links + xml_part;
                }
                desc = Regex.Replace(desc, "{MENU_LINKS}", xml_links);
            } finally {
                PtaUtil.CloseDataReader(bboardDR);
            }
            return(desc);
        }