/* * Box Social™ * http://boxsocial.net/ * Copyright © 2007, David Lachlan Smith * * $Id:$ * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 3 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ using System; using System.Collections; using System.Configuration; using System.Data; using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging; using System.Drawing.Text; using System.Web; using BoxSocial; using BoxSocial.Internals; using BoxSocial.IO; namespace BoxSocial.FrontEnd { public partial class captcha : TPage { protected void Page_Load(object sender, EventArgs e) { if (Request.QueryString["sid"] != session.SessionId) { core.Display.ShowMessage("Unauthorised", "You are unauthorised to do this action."); return; } long confirmId = 0; try { confirmId = long.Parse(Request.QueryString["secureid"]); } catch { core.Display.ShowMessage("Unauthorised", "You are unauthorised to do this action."); return; } DataTable confirmTable = db.Query(string.Format("SELECT confirm_code FROM confirm WHERE (confirm_type = 1 OR confirm_type = 2 OR confirm_type = 3) AND confirm_id = {0} AND session_id = '{1}'", confirmId, Mysql.Escape(session.SessionId))); if (confirmTable.Rows.Count != 1) { core.Display.ShowMessage("Unauthorised", "You are unauthorised to do this action."); return; } string confirmString = (string)confirmTable.Rows[0]["confirm_code"]; Response.Clear(); Response.ContentType = "image/jpeg"; int width = 350; int height = 120; Bitmap captchaImage = GenerateCaptcha(width, height, confirmString); /*Bitmap captchaImage = new Bitmap(width, height, PixelFormat.Format32bppArgb); Graphics g = Graphics.FromImage(captchaImage); g.Clear(Color.LightYellow); g.SmoothingMode = SmoothingMode.HighQuality; g.TextRenderingHint = TextRenderingHint.AntiAlias; Random rand = new Random(); Image img; if (rand.NextDouble() > 0.5) { img = Image.FromFile(Server.MapPath(@"\images\captcha_1.jpg")); } else { img = Image.FromFile(Server.MapPath(@"\images\captcha_2.jpg")); } TextureBrush tbt = new TextureBrush(img, new Rectangle(new Point((int)(500 * rand.NextDouble()), (int)(500 * rand.NextDouble())), new Size(400, 200))); g.FillRectangle(tbt, new Rectangle(new Point(0, 0), new Size(width, height))); //char[] chars = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' }; for (int i = 0; i < confirmString.Length; i++) { Matrix transformMatrix = new Matrix(1F, 0F, 0F, 1F, i * 30F + (float)(10 * rand.NextDouble()), 10F + (float)(10 * rand.NextDouble())); transformMatrix.Shear((float)(0.15 * rand.NextDouble()), (float)(0.15 * rand.NextDouble())); transformMatrix.Rotate(10F - (float)(5 * rand.NextDouble())); g.Transform = transformMatrix; //g.TransformPoints(CoordinateSpace.World, CoordinateSpace.World, new Point[] { new Point(1, 1), new Point(1, 50), new Point(50,50), new Point(50,1) }); GraphicsPath gp = new GraphicsPath(); //int j = (int)(rand.NextDouble() * chars.Length); if (rand.NextDouble() > 0.5) { gp.AddString(confirmString[i].ToString(), new FontFamily("Times New Roman"), (int)FontStyle.Bold, 35F + (float)(20 * rand.NextDouble()), new PointF(2F, 2F), StringFormat.GenericTypographic); } else { gp.AddString(confirmString[i].ToString(), new FontFamily("Arial"), (int)FontStyle.Bold, 35F + (float)(20 * rand.NextDouble()), new PointF(2F, 2F), StringFormat.GenericTypographic); } gp.Transform(transformMatrix); PointF[] pts = gp.PathPoints; Color[] colours = new Color[pts.Length]; for (int j = 0; j < pts.Length; j++) { colours[j] = captchaImage.GetPixel((int)pts[j].X, (int)pts[j].Y); } int[] mean = new int[3]; int[] geomean = new int[3]; for (int j = 0; j < colours.Length; j++) { mean[0] += colours[j].R; mean[1] += colours[j].G; mean[2] += colours[j].B; geomean[0] += (int)Math.Pow(colours[j].R, 2); geomean[1] += (int)Math.Pow(colours[j].G, 2); geomean[2] += (int)Math.Pow(colours[j].B, 2); } Color meanColour = Color.FromArgb(mean[0] / colours.Length, mean[1] / colours.Length, mean[2] / colours.Length); Color geomeanColour = Color.FromArgb((int)Math.Pow(geomean[0] / colours.Length, 0.5), (int)Math.Pow((double)geomean[1] / colours.Length, 0.5), (int)Math.Pow((double)geomean[2] / colours.Length, 0.5)); Color inverseMean = Color.FromArgb(255 - meanColour.R, 255 - meanColour.G, 255 - meanColour.B); Color inverseGeomean = Color.FromArgb(255 - geomeanColour.R, 255 - geomeanColour.G, 255 - geomeanColour.B); TextureBrush tb = new TextureBrush(img, new Rectangle(new Point((int)(500 * rand.NextDouble()), (int)(500 * rand.NextDouble())), new Size(200, 200))); g.FillPolygon(tb, pts); Color pen = captchaImage.GetPixel((int)pts[0].X, (int)pts[0].Y); Color pen2 = captchaImage.GetPixel((int)pts[pts.Length / 4].X, (int)pts[pts.Length / 4].Y); Color pen3 = captchaImage.GetPixel((int)pts[pts.Length / 4 * 2].X, (int)pts[pts.Length / 4 * 2].Y); Color pen4 = captchaImage.GetPixel((int)pts[pts.Length / 4 * 3].X, (int)pts[pts.Length / 4 * 3].Y); Color npen = Color.FromArgb(255 - (int)Math.Pow((double)pen.R * pen2.R * pen3.R * pen4.R, 1 / 4.0), 255 - (int)Math.Pow((double)pen.G * pen2.G * pen3.G * pen4.G, 1 / 4), 255 - (int)Math.Pow((double)pen.B * pen2.B * pen3.B * pen4.B, 1 / 4.0)); Color npen2 = Color.FromArgb(255 - (pen.R + pen2.R + pen3.R + pen4.R) / 4, 255 - (pen.G + pen2.G + pen3.G + pen4.G) / 4, 255 - (pen.B + pen2.B + pen3.B + pen4.B) / 4); //Color npen = Color.FromArgb((int)((255 - npen2.R) * rand.NextDouble() * 0.5), (int)((255 - npen2.G) * rand.NextDouble() * 0.5), (int)((255 - npen2.B) * rand.NextDouble() * 0.5)); HatchBrush hb = new HatchBrush((HatchStyle)((int)(50 * rand.NextDouble())), inverseMean, meanColour); g.DrawPolygon(new Pen(npen2, 0.5F), pts); g.FillPolygon(hb, pts); g.TranslateTransform(2, 2); hb = new HatchBrush((HatchStyle)((int)(50 * rand.NextDouble())), geomeanColour, inverseGeomean); g.DrawPolygon(new Pen(npen, 1.5F), pts); g.FillPolygon(hb, pts); g.DrawLine(new Pen(npen, 0.5F), new PointF(pts[pts.Length / 3].X + 20 * (float)rand.NextDouble(), pts[pts.Length / 3].Y - 20 * (float)rand.NextDouble()), new PointF(pts[pts.Length / 3 * 2].X - 20 * (float)rand.NextDouble(), pts[pts.Length / 3 * 2].Y + 20 * (float)rand.NextDouble())); g.DrawLine(new Pen(npen2, 0.5F), new PointF(pts[pts.Length / 3].X + 20 * (float)rand.NextDouble(), pts[pts.Length / 3].Y + 20 * (float)rand.NextDouble()), new PointF(pts[pts.Length / 3 * 2].X - 20 * (float)rand.NextDouble(), pts[pts.Length / 3 * 2].Y - 20 * (float)rand.NextDouble())); }*/ ImageCodecInfo encoderInfo = GetEncoderInfo("image/jpeg"); EncoderParameter encoderParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 90L); EncoderParameters encoderParams = new EncoderParameters(1); encoderParams.Param[0] = encoderParam; captchaImage.Save(Response.OutputStream, encoderInfo, encoderParams); } /// /// http://www.c-sharpcorner.com/UploadFile/scottlysle/WatermarkCS05072007024947AM/WatermarkCS.aspx /// /// /// private static ImageCodecInfo GetEncoderInfo(String mimeType) { int j; ImageCodecInfo[] encoders; encoders = ImageCodecInfo.GetImageEncoders(); for (j = 0; j < encoders.Length; ++j) { if (encoders[j].MimeType == mimeType) return encoders[j]; } return null; } private Bitmap GenerateCaptcha(int width, int height, string confirmString) { int chars = confirmString.Length; int letterWidth = (int)(width / (double)chars); Bitmap captchaImage = new Bitmap(width, height, PixelFormat.Format32bppArgb); Graphics g = Graphics.FromImage(captchaImage); g.Clear(Color.LightYellow); g.SmoothingMode = SmoothingMode.HighQuality; g.TextRenderingHint = TextRenderingHint.AntiAlias; PaintBackground(g, width, height, chars); for (int i = 0; i < chars; i++) { PaintLetter(g, confirmString[i], i * letterWidth, letterWidth, height); } return captchaImage; } private void PaintBackground(Graphics g, int width, int height, int letters) { int blockWidth = (int)((width - 10 * letters) / (5.0 * letters)); int blocksW = width / blockWidth; int blocksH = height / blockWidth; Random rand = new Random((int)(DateTime.Now.Ticks & 0x0000FFFF)); int firstOffsetX = (int)(rand.NextDouble() * 5); int offsetY = 0; for (int i = 0; i < (blocksW + blocksH + 2); i++) { Pen pen = new Pen(RandomBackgroundColour(), 2.5F); offsetY += rand.Next(-2, 2); for (int j = 0; j < blocksH + 2; j++) { g.DrawLine(pen, new Point(i * blockWidth - firstOffsetX, j * blockWidth + offsetY), new Point(i * blockWidth - firstOffsetX, j * blockWidth + offsetY + blockWidth)); g.DrawLine(pen, new Point(i * blockWidth - firstOffsetX, j * blockWidth + offsetY + blockWidth), new Point(i * blockWidth - firstOffsetX + blockWidth, j * blockWidth + offsetY + blockWidth)); } } } private void PaintLetter(Graphics g, char letter, int left, int width, int height) { int blockHeight = (int)((height * 0.75) / 7.0); int blockWidth = (int)((width * 0.75) / 5.0); blockWidth = blockHeight = Math.Min(blockWidth, blockHeight); int offsetX = (width - 5 * blockWidth) / 2; int offsetY = (height - 7 * blockHeight) / 2; byte[] b = GetLetter(letter); Random rand = new Random((int)(DateTime.Now.Ticks & 0x0000FFFF)); int upDown = rand.Next(-1 * offsetY / 2, offsetY / 2); for (int i = 0; i < 7; i++) { for (int j = 0; j < 5; j++) { if (b[i * 5 + j] > 0) { int widthVariation = rand.Next(-2, 2); int heightVariation = rand.Next(-2, 2); int leftVariation = rand.Next(-2, 2); int topVariation = rand.Next(-2, 2); g.DrawRectangle(new Pen(RandomColour()), new Rectangle(offsetX + left + blockWidth * j + leftVariation, offsetY + blockHeight * i + upDown + topVariation, blockWidth + widthVariation, blockHeight + heightVariation)); } } } } private byte[] GetLetter(char letter) { byte[] b = null; switch (letter) { case '0': b = new byte[] {0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0}; break; case '1': b = new byte[] {0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0}; break; case '2': b = new byte[] {0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1}; break; case '3': b = new byte[] {1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0}; break; case '4': b = new byte[] {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0}; break; case '5': b = new byte[] {1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0}; break; case '6': b = new byte[] {0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0}; break; case '7': b = new byte[] {1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0}; break; case '8': b = new byte[] {0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0}; break; case '9': b = new byte[] {0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0}; break; case 'A': b = new byte[] {0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1}; break; case 'B': b = new byte[] {1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0}; break; case 'C': b = new byte[] {0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0}; break; case 'D': b = new byte[] {1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0}; break; case 'E': b = new byte[] {1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1}; break; case 'F': b = new byte[] {1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0}; break; case 'G': b = new byte[] {0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0}; break; case 'H': b = new byte[] {1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1}; break; case 'I': b = new byte[] {1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1}; break; case 'J': b = new byte[] {1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0}; break; case 'K': b = new byte[] {1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1}; break; case 'L': b = new byte[] {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1}; break; case 'M': b = new byte[] {0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1}; break; case 'N': b = new byte[] {1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1}; break; case 'O': b = new byte[] {0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0}; break; case 'P': b = new byte[] {1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0}; break; case 'Q': b = new byte[] {0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1}; break; case 'R': b = new byte[] {1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1}; break; case 'S': b = new byte[] {0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0}; break; case 'T': b = new byte[] {1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0}; break; case 'U': b = new byte[] {1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0}; break; case 'V': b = new byte[] {1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0}; break; case 'W': b = new byte[] {1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0}; break; case 'X': b = new byte[] {1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1}; break; case 'Y': b = new byte[] {1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0}; break; case 'Z': b = new byte[] {1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1}; break; } return b; } private Color RandomColour() { Random rand = new Random((int)(DateTime.Now.Ticks & 0x0000FFFF)); double d = rand.NextDouble(); return Display.HlsToRgb(d * 360, 1.0, 0.45); } private Color RandomBackgroundColour() { Random rand = new Random((int)(DateTime.Now.Ticks & 0x0000FFFF)); double d = rand.NextDouble(); return Display.HlsToRgb(d * 360, 0.75, 0.95); } } }