1 //this file is part of MimeTools (plugin for Notepad++) 2 //Copyright (C)2013 Robert Meakins <rmeakins@users.sf.net> 3 // 4 //This program is free software; you can redistribute it and/or 5 //modify it under the terms of the GNU General Public License 6 //as published by the Free Software Foundation; either 7 //version 2 of the License, or (at your option) any later version. 8 // 9 //This program is distributed in the hope that it will be useful, 10 //but WITHOUT ANY WARRANTY; without even the implied warranty of 11 //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 //GNU General Public License for more details. 13 // 14 //You should have received a copy of the GNU General Public License 15 //along with this program; if not, write to the Free Software 16 //Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 17 module npp_mimetools.saml; 18 19 20 private static import npp_mimetools.b64; 21 private static import npp_mimetools.tinflate; 22 private static import npp_mimetools.url; 23 24 enum int SAML_DECODE_ERROR_URLDECODE = -1; 25 enum int SAML_DECODE_ERROR_BASE64DECODE = -2; 26 enum int SAML_DECODE_ERROR_INFLATE = -3; 27 enum int SAML_MESSAGE_MAX_SIZE = 200000; 28 29 nothrow 30 int samlDecode(ref char[] dest, const char[] encodedSamlStr) 31 32 in 33 { 34 assert(dest.length != 0); 35 } 36 37 do 38 { 39 char[] pUrlDecodedText = new char[encodedSamlStr.length]; 40 41 dest[] = '\0'; 42 pUrlDecodedText[] = '\0'; 43 44 // URL Decode 45 size_t urlDecodedLen = npp_mimetools.url.UrlToAscii(pUrlDecodedText, encodedSamlStr); 46 47 if (urlDecodedLen < 0) { 48 return .SAML_DECODE_ERROR_URLDECODE; 49 } 50 51 char[] base64DecodedText = new char[urlDecodedLen + 1]; 52 53 int base64DecodedLen = npp_mimetools.b64.base64Decode(base64DecodedText, pUrlDecodedText, urlDecodedLen, true, false); 54 55 if (base64DecodedLen < 0) { 56 return .SAML_DECODE_ERROR_BASE64DECODE; 57 } 58 59 base64DecodedText[base64DecodedLen] = '\0'; 60 61 // A SAML message should be longer than 10 chars 62 if (base64DecodedLen < 10) { 63 return .SAML_DECODE_ERROR_BASE64DECODE; 64 } 65 66 // If the first 5 chars are "<?xml" or "<saml", no need to inflate 67 if ((base64DecodedText[0] == '<') && (base64DecodedText[3] == 'm') && (base64DecodedText[4] == 'l')) { 68 dest[0 .. base64DecodedLen] = base64DecodedText[0 .. base64DecodedLen]; 69 70 return base64DecodedLen; 71 } 72 73 // Inflate the Base64 decoded text 74 char[] inflatedText = new char[.SAML_MESSAGE_MAX_SIZE]; 75 uint inflatedTextLen = 0; 76 77 npp_mimetools.tinflate.tinf_init(); 78 int inflateReturnCode = npp_mimetools.tinflate.tinf_uncompress(inflatedText, inflatedTextLen, base64DecodedText); 79 80 if (inflateReturnCode != npp_mimetools.tinflate.TINF_OK) { 81 return .SAML_DECODE_ERROR_INFLATE; 82 } 83 84 dest[0 .. inflatedTextLen] = inflatedText[0 .. inflatedTextLen]; 85 86 // If the first 5 chars are not "<?xml" or "<saml", there's a problem 87 if (!((dest[0] == '<') && (dest[3] == 'm') && (dest[4] == 'l'))) { 88 return .SAML_DECODE_ERROR_INFLATE; 89 } 90 91 return inflatedTextLen; 92 }