1 /* 2 * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 ******************************************************************************* 26 * Copyright (C) 2003-2004, International Business Machines Corporation and * 27 * others. All Rights Reserved. * 28 ******************************************************************************* 29 */ 30 import java.io.IOException; 31 import java.io.InputStream; 32 import java.io.UnsupportedEncodingException; 33 import java.text.ParseException; 34 35 import sun.net.idn.StringPrep; 36 import sun.text.normalizer.UCharacterIterator; 37 38 /** 39 * @author ram 40 * 41 * This is a dumb implementation of NFS4 profiles. It is a direct port of 42 * C code, does not use Object Oriented principles. Quick and Dirty implementation 43 * for testing. 44 */ 45 public final class NFS4StringPrep { 46 47 private StringPrep nfscss = null; 48 private StringPrep nfscsi = null; 49 private StringPrep nfscis = null; 50 private StringPrep nfsmxp = null; 51 private StringPrep nfsmxs = null; 52 //singleton instance 53 private static final NFS4StringPrep prep = new NFS4StringPrep(); 54 55 56 private NFS4StringPrep (){ 57 ClassLoader loader = NFS4StringPrep.class.getClassLoader(); 58 try{ 59 InputStream nfscsiFile = loader.getResourceAsStream("nfscsi.spp"); 60 nfscsi = new StringPrep(nfscsiFile); 61 nfscsiFile.close(); 62 63 InputStream nfscssFile = loader.getResourceAsStream("nfscss.spp"); 64 nfscss = new StringPrep(nfscssFile); 65 nfscssFile.close(); 66 67 InputStream nfscisFile = loader.getResourceAsStream("nfscis.spp"); 68 nfscis = new StringPrep(nfscisFile); 69 nfscisFile.close(); 70 71 InputStream nfsmxpFile = loader.getResourceAsStream("nfsmxp.spp"); 72 nfsmxp = new StringPrep(nfsmxpFile); 73 nfsmxpFile.close(); 74 75 InputStream nfsmxsFile = loader.getResourceAsStream("nfsmxs.spp"); 76 nfsmxs = new StringPrep(nfsmxsFile); 77 nfsmxsFile.close(); 78 }catch(IOException e){ 79 throw new RuntimeException(e.toString()); 80 } 81 } 82 83 private static byte[] prepare(byte[] src, StringPrep prep) 84 throws ParseException, UnsupportedEncodingException{ 85 String s = new String(src, "UTF-8"); 86 UCharacterIterator iter = UCharacterIterator.getInstance(s); 87 StringBuffer out = prep.prepare(iter,StringPrep.DEFAULT); 88 return out.toString().getBytes("UTF-8"); 89 } 90 91 public static byte[] cs_prepare(byte[] src, boolean isCaseSensitive) 92 throws ParseException, UnsupportedEncodingException{ 93 if(isCaseSensitive == true ){ 94 return prepare(src, prep.nfscss); 95 }else{ 96 return prepare(src, prep.nfscsi); 97 } 98 } 99 100 public static byte[] cis_prepare(byte[] src) 101 throws IOException, ParseException, UnsupportedEncodingException{ 102 return prepare(src, prep.nfscis); 103 } 104 105 /* sorted array for binary search*/ 106 private static final String[] special_prefixes={ 107 "ANONYMOUS", 108 "AUTHENTICATED", 109 "BATCH", 110 "DIALUP", 111 "EVERYONE", 112 "GROUP", 113 "INTERACTIVE", 114 "NETWORK", 115 "OWNER", 116 }; 117 118 119 /* binary search the sorted array */ 120 private static final int findStringIndex(String[] sortedArr,String target){ 121 122 int left, middle, right,rc; 123 124 left =0; 125 right= sortedArr.length-1; 126 127 while(left <= right){ 128 middle = (left+right)/2; 129 rc= sortedArr[middle].compareTo(target); 130 131 if(rc<0){ 132 left = middle+1; 133 }else if(rc >0){ 134 right = middle -1; 135 }else{ 136 return middle; 137 } 138 } 139 return -1; 140 } 141 private static final char AT_SIGN = '@'; 142 143 public static byte[] mixed_prepare(byte[] src) 144 throws IOException, ParseException, UnsupportedEncodingException{ 145 String s = new String(src, "UTF-8"); 146 int index = s.indexOf(AT_SIGN); 147 StringBuffer out = new StringBuffer(); 148 149 if(index > -1){ 150 /* special prefixes must not be followed by suffixes! */ 151 String prefixString = s.substring(0,index); 152 int i= findStringIndex(special_prefixes, prefixString); 153 String suffixString = s.substring(index+1, s.length()); 154 if(i>-1 && !suffixString.equals("")){ 155 throw new ParseException("Suffix following a special index", -1); 156 } 157 UCharacterIterator prefix = UCharacterIterator.getInstance(prefixString); 158 UCharacterIterator suffix = UCharacterIterator.getInstance(suffixString); 159 out.append(prep.nfsmxp.prepare(prefix,StringPrep.DEFAULT)); 160 out.append(AT_SIGN); // add the delimiter 161 out.append(prep.nfsmxs.prepare(suffix, StringPrep.DEFAULT)); 162 }else{ 163 UCharacterIterator iter = UCharacterIterator.getInstance(s); 164 out.append(prep.nfsmxp.prepare(iter,StringPrep.DEFAULT)); 165 166 } 167 return out.toString().getBytes("UTF-8"); 168 } 169 170 }