001 package com.croftsoft.core.net.news; 002 003 import java.io.*; 004 import java.net.*; 005 import java.util.*; 006 007 import com.croftsoft.core.lang.Pair; 008 import com.croftsoft.core.lang.StringLib; 009 import com.croftsoft.core.security.Authentication; 010 import com.croftsoft.core.security.Identifier; 011 import com.croftsoft.core.security.PreIdentifier; 012 import com.croftsoft.core.util.log.Log; 013 import com.croftsoft.core.util.log.PrintStreamLog; 014 015 /********************************************************************* 016 * Static library methods for NNTP (RFC 977). 017 * 018 * @author 019 * <a href="https://www.croftsoft.com/">David Wallace Croft</A> 020 * @version 021 * 2001-08-03 022 * @since 023 * 2001-07-23 024 *********************************************************************/ 025 026 public final class NntpLib 027 implements NntpConstants 028 ////////////////////////////////////////////////////////////////////// 029 ////////////////////////////////////////////////////////////////////// 030 { 031 032 /********************************************************************* 033 * Posts a test message to a test newsgroup. 034 *********************************************************************/ 035 public static void main ( String [ ] args ) 036 throws IOException 037 ////////////////////////////////////////////////////////////////////// 038 { 039 String nntpServer = args [ 0 ]; 040 041 String username = args [ 1 ]; 042 043 String password = args [ 2 ]; 044 045 UsenetMessage usenetMessage = new UsenetMessage ( 046 args [ 3 ], // from 047 "alt.test", // newsgroup 048 "test", // subject 049 "This is a test." ); // body 050 051 post ( 052 nntpServer, 053 new PreIdentifier ( username, password ), 054 usenetMessage, 055 new PrintStreamLog ( System.out ) ); 056 } 057 058 ////////////////////////////////////////////////////////////////////// 059 ////////////////////////////////////////////////////////////////////// 060 061 /********************************************************************* 062 * Sends username and password. 063 * 064 * Synchronizes on the NntpSocket. 065 *********************************************************************/ 066 public static String authenticate ( 067 NntpSocket nntpSocket, 068 String username, 069 String password ) 070 throws IOException, SecurityException 071 ////////////////////////////////////////////////////////////////////// 072 { 073 synchronized ( nntpSocket ) 074 { 075 076 String responseCode 077 = nntpSocket.command ( COMMAND_AUTHINFO + " USER " + username ); 078 079 if ( responseCode.startsWith ( "502" ) ) 080 { 081 // 502 Authentication Failed 082 083 throw new SecurityException ( responseCode ); 084 } 085 086 // 381 More Authentication Required 087 088 Log log = nntpSocket.getLog ( ); 089 090 nntpSocket.setLog ( null ); 091 092 responseCode 093 = nntpSocket.command ( COMMAND_AUTHINFO + " PASS " + password ); 094 095 nntpSocket.setLog ( log ); 096 097 if ( responseCode.startsWith ( "502" ) ) 098 { 099 // 502 Authentication Failed 100 101 throw new SecurityException ( responseCode ); 102 } 103 104 // 281 Authentication Accepted 105 106 return responseCode; 107 108 } 109 } 110 111 /********************************************************************* 112 * Replaces lines that start with "." with "..", 113 * appends CR_LF to each line, then 114 * adds a final line of "." + CR_LF. 115 *********************************************************************/ 116 public static StringBuffer encodeLines ( String [ ] lines ) 117 ////////////////////////////////////////////////////////////////////// 118 { 119 StringBuffer stringBuffer = new StringBuffer ( ); 120 121 for ( int i = 0; i < lines.length; i++ ) 122 { 123 String line = lines [ i ]; 124 125 if ( line.startsWith ( "." ) ) 126 { 127 stringBuffer.append ( "." ); 128 } 129 130 stringBuffer.append ( line ); 131 132 stringBuffer.append ( CR_LF ); 133 } 134 135 stringBuffer.append ( "." + CR_LF ); 136 137 return stringBuffer; 138 } 139 140 /********************************************************************* 141 * Encodes a message body in preparation for an NNTP POST transmission. 142 * 143 * <pre> 144 * return encodeLines ( 145 * StringLib.toStringArray ( messageBody ) ).toString ( ); 146 * </pre> 147 *********************************************************************/ 148 public static String encode ( String messageBody ) 149 ////////////////////////////////////////////////////////////////////// 150 { 151 return encodeLines ( 152 StringLib.toStringArray ( messageBody ) ).toString ( ); 153 } 154 155 /********************************************************************* 156 * Replaces lines that start with ".." with ".". 157 *********************************************************************/ 158 public static void decodeLines ( String [ ] lines ) 159 ////////////////////////////////////////////////////////////////////// 160 { 161 for ( int i = 0; i < lines.length; i++ ) 162 { 163 lines [ i ] = decodeLine ( lines [ i ] ); 164 } 165 } 166 167 /********************************************************************* 168 * Replaces starting ".." with ".". 169 *********************************************************************/ 170 public static String decodeLine ( String line ) 171 ////////////////////////////////////////////////////////////////////// 172 { 173 if ( line.startsWith ( ".." ) ) 174 { 175 return line.substring ( 1 ); 176 } 177 178 return new String ( line ); 179 } 180 181 public static String post ( 182 String nntpServer, 183 Identifier identifier, 184 UsenetMessage usenetMessage, 185 Log log ) 186 throws IOException 187 ////////////////////////////////////////////////////////////////////// 188 { 189 String responseCode = null; 190 191 NntpSocket nntpSocket = null; 192 193 try 194 { 195 nntpSocket = new NntpSocket ( nntpServer, log ); 196 197 nntpSocket.setSoLinger ( true, 30 ); // timeout after 30 seconds 198 199 responseCode = nntpSocket.getResponseCode ( ); 200 201 if ( !nntpSocket.getPostingAllowed ( ) ) 202 { 203 throw new IOException ( responseCode ); 204 } 205 206 responseCode = nntpSocket.command ( NntpConstants.COMMAND_POST ); 207 208 if ( responseCode.startsWith ( "480" ) 209 && ( identifier != null ) ) 210 { 211 // 480 Authentication Required 212 213 Authentication authentication 214 = identifier.getAuthentication ( ); 215 216 if ( authentication != null ) 217 { 218 responseCode = authenticate ( 219 nntpSocket, 220 authentication.getUsername ( ), 221 authentication.getPassword ( ) ); 222 223 responseCode 224 = nntpSocket.command ( NntpConstants.COMMAND_POST ); 225 } 226 } 227 228 if ( !responseCode.startsWith ( "340" ) ) 229 { 230 throw new IOException ( responseCode ); 231 } 232 233 responseCode = nntpSocket.command ( usenetMessage.toString ( ) ); 234 235 if ( !responseCode.startsWith ( "240" ) ) 236 { 237 throw new IOException ( responseCode ); 238 } 239 240 responseCode = nntpSocket.command_QUIT ( ); 241 } 242 finally 243 { 244 if ( nntpSocket != null ) 245 { 246 nntpSocket.close ( ); 247 } 248 } 249 250 return responseCode; 251 } 252 253 /* 254 public static String post ( 255 String nntpServer, 256 Identifier identifier, 257 Pair [ ] messageHeaderPairs, 258 String messageBody, 259 Log log ) 260 throws IOException 261 ////////////////////////////////////////////////////////////////////// 262 { 263 UsenetMessage usenetMessage = new UsenetMessage ( ); 264 265 for ( int i = 0; i < messageHeaderPairs.length; i++ ) 266 { 267 Pair headerPair = messageHeaderPairs [ i ]; 268 269 usenetMessage.setHeader ( headerPair.name, headerPair.value ); 270 } 271 272 usenetMessage.setBody ( messageBody ); 273 274 return NntpLib.post ( 275 nntpServer, username, password, usenetMessage, log ); 276 } 277 */ 278 279 ////////////////////////////////////////////////////////////////////// 280 ////////////////////////////////////////////////////////////////////// 281 282 private NntpLib ( ) { } 283 284 ////////////////////////////////////////////////////////////////////// 285 ////////////////////////////////////////////////////////////////////// 286 }