001package org.apache.maven.scm.provider.cvslib.command.login; 002 003/* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022import org.apache.maven.scm.ScmException; 023import org.apache.maven.scm.log.ScmLogger; 024 025import java.io.BufferedReader; 026import java.io.File; 027import java.io.FileReader; 028import java.io.FileWriter; 029import java.io.IOException; 030import java.io.PrintWriter; 031 032/** 033 * Adds an new entry to a CVS password file. 034 * 035 * 036 * @todo Update this class for support password storage in cvsnt. CVSNT use the windows registry, so, we need a jni 037 * tool for access to the windows registry 038 */ 039public class CvsPass 040{ 041 /** 042 * CVS Root 043 */ 044 private String cvsRoot = null; 045 046 /** 047 * Password file to add password to 048 */ 049 private File passFile = null; 050 051 /** 052 * Password to add to file 053 */ 054 private String password = null; 055 056 private ScmLogger logger; 057 058 /** 059 * Array contain char conversion data 060 */ 061 private final char[] shifts = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 062 24, 25, 26, 27, 28, 29, 30, 31, 114, 120, 53, 79, 96, 109, 72, 108, 70, 64, 76, 67, 116, 74, 68, 87, 111, 52, 063 75, 119, 49, 34, 82, 81, 95, 65, 112, 86, 118, 110, 122, 105, 41, 57, 83, 43, 46, 102, 40, 89, 38, 103, 45, 50, 064 42, 123, 91, 35, 125, 55, 54, 66, 124, 126, 59, 47, 92, 71, 115, 78, 88, 107, 106, 56, 36, 121, 117, 104, 101, 065 100, 69, 73, 99, 63, 94, 93, 39, 37, 61, 48, 58, 113, 32, 90, 44, 98, 60, 51, 33, 97, 62, 77, 84, 80, 85, 223, 066 225, 216, 187, 166, 229, 189, 222, 188, 141, 249, 148, 200, 184, 136, 248, 190, 199, 170, 181, 204, 138, 232, 067 218, 183, 255, 234, 220, 247, 213, 203, 226, 193, 174, 172, 228, 252, 217, 201, 131, 230, 197, 211, 145, 238, 068 161, 179, 160, 212, 207, 221, 254, 173, 202, 146, 224, 151, 140, 196, 205, 130, 135, 133, 143, 246, 192, 159, 069 244, 239, 185, 168, 215, 144, 139, 165, 180, 157, 147, 186, 214, 176, 227, 231, 219, 169, 175, 156, 206, 198, 070 129, 164, 150, 210, 154, 177, 134, 127, 182, 128, 158, 208, 162, 132, 167, 209, 149, 241, 153, 251, 237, 236, 071 171, 195, 243, 233, 253, 240, 194, 250, 191, 155, 142, 137, 245, 235, 163, 242, 178, 152}; 072 073 /** 074 * Create a CVS task using the default cvspass file location. 075 */ 076 public CvsPass( ScmLogger logger ) 077 { 078 passFile = new File( System.getProperty( "cygwin.user.home", System.getProperty( "user.home" ) ) + File 079 .separatorChar + ".cvspass" ); 080 this.logger = logger; 081 } 082 083 /** 084 * Does the work. 085 * 086 * @throws ScmException if something is missing 087 * @throws IOException if something goes wrong 088 */ 089 public final void execute() 090 throws ScmException, IOException 091 { 092 if ( cvsRoot == null ) 093 { 094 throw new ScmException( "cvsroot is required" ); 095 } 096 097 if ( logger.isDebugEnabled() ) 098 { 099 logger.debug( "cvsRoot: " + cvsRoot ); 100 logger.debug( "passFile: " + passFile ); 101 } 102 103 BufferedReader reader = null; 104 105 PrintWriter writer = null; 106 try 107 { 108 StringBuilder buf = new StringBuilder(); 109 110 if ( passFile.exists() ) 111 { 112 reader = new BufferedReader( new FileReader( passFile ) ); 113 114 String line = null; 115 116 while ( ( line = reader.readLine() ) != null ) 117 { 118 if ( !line.startsWith( cvsRoot ) && !line.startsWith( "/1 " + cvsRoot ) ) 119 { 120 buf.append( line ).append( "\n" ); 121 } 122 else 123 { 124 if ( logger.isDebugEnabled() ) 125 { 126 logger.debug( "cvsroot " + cvsRoot + " already exist in " + passFile.getAbsolutePath() 127 + ". SKIPPED." ); 128 } 129 130 return; 131 } 132 } 133 } 134 else 135 { 136 passFile.getParentFile().mkdirs(); 137 } 138 139 if ( password == null ) 140 { 141 throw new ScmException( "password is required. You must run a 'cvs -d " + cvsRoot 142 + " login' first or provide it in the connection url." ); 143 } 144 145 //logger.debug( "password: " + password ); 146 147 String pwdfile = buf.toString() + "/1 " + cvsRoot + " A" + mangle( password ); 148 149 if ( logger.isDebugEnabled() ) 150 { 151 logger.debug( "Writing -> " + pwdfile + " in " + passFile.getAbsolutePath() ); 152 } 153 154 writer = new PrintWriter( new FileWriter( passFile ) ); 155 156 writer.println( pwdfile ); 157 } 158 finally 159 { 160 if ( reader != null ) 161 { 162 try 163 { 164 reader.close(); 165 } 166 catch ( IOException e ) 167 { 168 // ignore 169 } 170 } 171 if ( writer != null ) 172 { 173 writer.close(); 174 } 175 } 176 } 177 178 private String mangle( String password ) 179 { 180 StringBuilder buf = new StringBuilder(); 181 for ( int i = 0; i < password.length(); i++ ) 182 { 183 buf.append( shifts[password.charAt( i )] ); 184 } 185 return buf.toString(); 186 } 187 188 /** 189 * The CVS repository to add an entry for. 190 * 191 * @param cvsRoot the CVS repository 192 */ 193 public void setCvsroot( String cvsRoot ) 194 { 195 this.cvsRoot = cvsRoot; 196 } 197 198 /** 199 * Password file to add the entry to. 200 * 201 * @param passFile the password file. 202 */ 203 public void setPassfile( File passFile ) 204 { 205 this.passFile = passFile; 206 } 207 208 /** 209 * Password to be added to the password file. 210 * 211 * @param password the password. 212 */ 213 public void setPassword( String password ) 214 { 215 this.password = password; 216 } 217 218}