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 static import npp_mimetools.b64; 40 static import npp_mimetools.tinflate; 41 static import npp_mimetools.url; 42 43 char[] pUrlDecodedText = new char[encodedSamlStr.length]; 44 45 dest[] = '\0'; 46 pUrlDecodedText[] = '\0'; 47 48 // URL Decode 49 size_t urlDecodedLen = npp_mimetools.url.UrlToAscii(pUrlDecodedText, encodedSamlStr); 50 51 if (urlDecodedLen < 0) { 52 return .SAML_DECODE_ERROR_URLDECODE; 53 } 54 55 char[] base64DecodedText = new char[urlDecodedLen + 1]; 56 57 int base64DecodedLen = npp_mimetools.b64.base64Decode(base64DecodedText, pUrlDecodedText, urlDecodedLen, true, false); 58 59 if (base64DecodedLen < 0) { 60 return .SAML_DECODE_ERROR_BASE64DECODE; 61 } 62 63 base64DecodedText[base64DecodedLen] = '\0'; 64 65 // A SAML message should be longer than 10 chars 66 if (base64DecodedLen < 10) { 67 return .SAML_DECODE_ERROR_BASE64DECODE; 68 } 69 70 // If the first 5 chars are "<?xml" or "<saml", no need to inflate 71 if ((base64DecodedText[0] == '<') && (base64DecodedText[3] == 'm') && (base64DecodedText[4] == 'l')) { 72 dest[0 .. base64DecodedLen] = base64DecodedText[0 .. base64DecodedLen]; 73 74 return base64DecodedLen; 75 } 76 77 // Inflate the Base64 decoded text 78 char[] inflatedText = new char[.SAML_MESSAGE_MAX_SIZE]; 79 uint inflatedTextLen = 0; 80 81 npp_mimetools.tinflate.tinf_init(); 82 int inflateReturnCode = npp_mimetools.tinflate.tinf_uncompress(inflatedText, inflatedTextLen, base64DecodedText); 83 84 if (inflateReturnCode != npp_mimetools.tinflate.TINF_OK) { 85 return .SAML_DECODE_ERROR_INFLATE; 86 } 87 88 dest[0 .. inflatedTextLen] = inflatedText[0 .. inflatedTextLen]; 89 90 // If the first 5 chars are not "<?xml" or "<saml", there's a problem 91 if (!((dest[0] == '<') && (dest[3] == 'm') && (dest[4] == 'l'))) { 92 return .SAML_DECODE_ERROR_INFLATE; 93 } 94 95 return inflatedTextLen; 96 }