Skip to content

Commit

Permalink
Support for custom auth methods
Browse files Browse the repository at this point in the history
To support #1 and #4
  • Loading branch information
RKuttruff committed May 26, 2022
1 parent ef04ec6 commit 34a6a76
Showing 1 changed file with 78 additions and 5 deletions.
83 changes: 78 additions & 5 deletions src/SMTPClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,13 @@ public class SMTPClient{

private static final Pattern COLON = Pattern.compile(":");

private static final String[] AUTH_METHODS = {
"PLAIN",
"XOAUTH2"
};

private static String authMethod;

static{
System.setProperty("line.separator", CRLF); //Since SMTP uses <CRLF>, set this as the default.
System.setProperty("java.net.preferIPv6Addresses", "true");
Expand All @@ -129,6 +136,8 @@ public class SMTPClient{
pass = null;
files = null;

authMethod = AUTH_METHODS[1];

stdIn = new BufferedReader(new InputStreamReader(System.in));

//A shutdown hook to make sure the socket is closed when the program exits
Expand Down Expand Up @@ -293,8 +302,12 @@ else if(curStart != -1){
return sb.toString();
}

private static void getXOAuth2Data(){

}

//Gets username and password (if necessary) and encodes them in Base64 for PLAIN authentication
private static void buildAuthData(){
private static void buildPlainAuthData(){
if(uName == null)
getUser();

Expand Down Expand Up @@ -344,12 +357,23 @@ private static void buildAuthData(){
Arrays.fill(auth, (byte)0);
}

private static void buildAuthData(){
switch(authMethod){
case "PLAIN":
buildPlainAuthData();
break;
case "XOAUTH2":
getXOAuth2Data();
break;
}
}

//Actually submit the authentication and return the response.
private static Response submitAuthentication(){
Response resp;

try{
out.print("AUTH PLAIN ");
out.printf("AUTH %s ", authMethod);
out.flush();

OutputStream os = socket.getOutputStream();
Expand Down Expand Up @@ -445,6 +469,7 @@ private static void splitCommandLine(String[] args){
boolean userSet = false; //-from option has been set
boolean rcptSet = false; //-to option has been set
boolean passSet = false; //-pass option has been set
boolean authSet = false; //-auth option has been set

for(String arg : args){
String originalArg = arg; //Save the value of the argument (for error messages)
Expand Down Expand Up @@ -514,9 +539,50 @@ else if(arg.equalsIgnoreCase("askpass")){

passSet = true;
}
else if(arg.equalsIgnoreCase("auth")){
if(authSet){
stdErr.println("Repeated argument: " + originalArg);
System.exit(ERR_BAD_COMMAND_LINE);
}

arg = splitKeyValue(arg);

if(arg == null){
stdErr.println("Invalid argument: " + originalArg);

System.exit(ERR_BAD_COMMAND_LINE);
}

String am = arg;

boolean valid = false;

for(String m : AUTH_METHODS)
if(am.equals(m)){
valid = true;
break;
}

if(!valid){
stdErr.println("Invalid auth method: " + am);

System.exit(ERR_INVALID_OPT);
}

authMethod = am;
authSet = true;
}
else if(arg.equalsIgnoreCase("help")){
help();
}
else if(arg.equalsIgnoreCase("list-auth")){
stdOut.println("Valid methods:\n");

for(String m : AUTH_METHODS)
stdOut.println("\t" + m);

System.exit(ERR_OK);
}
else if(arg.startsWith("type=")){
if(typeSet){
stdErr.println("Repeated argument: " + originalArg);
Expand Down Expand Up @@ -695,14 +761,15 @@ private static void rawClient(){
}
else if(autoAUTH){
buildAuthData();
logVerbose("AUTH PLAIN ****");
logVerbose(String.format("AUTH %s ****", authMethod));
resp = submitAuthentication();
resp.print();
autoAUTH = false;
if(resp.getResponseCodeType() == 5){
stdErr.println("SMTP Error - " + resp.getResponseCode());
System.exit(resp.getResponseCode());
}

continue;
}
else
Expand Down Expand Up @@ -817,7 +884,7 @@ private static void guiClient(){
}

buildAuthData();
logVerbose("AUTH PLAIN ****");
logVerbose(String.format("AUTH %s ****", authMethod));
resp = submitAuthentication();
logVerbose(resp);

Expand Down Expand Up @@ -938,7 +1005,7 @@ private static void fileClient(){
}

buildAuthData();
logVerbose("AUTH PLAIN ****");
logVerbose(String.format("AUTH %s ****", authMethod));
resp = submitAuthentication();
logVerbose(resp);

Expand Down Expand Up @@ -1214,6 +1281,12 @@ private static String[] split(Pattern p, CharSequence seq, int limit){
" recommended that this not be used to avoid the password being stored in an",
" immutable String object, rather than using a clearable character array.",
"",
" -auth=<AUTH method>",
" Sets the authentication method to use. Consult option -list-auth for valid options.",
"",
" -list-auth",
" Prints all implemented AUTH methods, then exits.",
"",
" -help",
" Prints this message, then exits.",
"",
Expand Down

0 comments on commit 34a6a76

Please sign in to comment.