using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Web;
using System.Globalization;
using System.Data;
namespace WmDirectAdminLibrary {
///
/// API Wrapper for DirectAdmin
/// created by W.L. Middelkoop, 14-aug-2009 @ 10:06hrs
///
public class WmDirectAdminApi {
protected static string serverApiUrl;
protected static string username;
protected static string password;
protected static CultureInfo usCulture;
public static void initDirectAdminApi(string serverIp, string apiUsername, string apiPassword) {
serverApiUrl = "http://" + serverIp + ":2222";
username = apiUsername;
password = apiPassword;
usCulture = new CultureInfo("en-US");
}
/// 2 started; 4 stopped (these odd codes come from Windows IIS where multiple states are possible, including starting, stopping, paused etc)
public static int getVirtualHostingStatus(string domainName) {
string domainsUrl = serverApiUrl + "/CMD_API_ADDITIONAL_DOMAINS?action=view&domain="+domainName;
string response = HttpUtility.UrlDecode(getResponseFromServer(domainsUrl, null)).ToLower();
if (response.IndexOf("suspended=yes") != -1) {
return 4;
} else if (response.IndexOf("suspended=no") != -1) {
return 2;
} else {
return -1;
}
}
public static bool startVirtualHosting(string domainName) {
int currentStatus = getVirtualHostingStatus(domainName);
if (currentStatus != 2) { // 2 is Windows IIS for started
return toggleVirtualHostingStatus(domainName);
}
return true; // status is already started
}
public static bool stopVirtualHosting(string domainName) {
int currentStatus = getVirtualHostingStatus(domainName);
if (currentStatus != 4) { // 4 is Windows IIS for stopped
return toggleVirtualHostingStatus(domainName);
}
return true; // status is already stopped
}
protected static bool toggleVirtualHostingStatus(string domainName) {
string url = serverApiUrl + "/CMD_API_DOMAIN";
List domainVariables = new List();
domainVariables.Add(new PostVariable("action", "select"));
domainVariables.Add(new PostVariable("suspend", domainName));
domainVariables.Add(new PostVariable("select0", domainName));
string response = HttpUtility.UrlDecode(getResponseFromServer(url, domainVariables));
if (response.StartsWith("error=0")) {
return true;
} else {
return false;
}
}
///
/// Returns a string[] of existing domains
///
public static string[] getVirtualHostingDomainNames() {
string url = serverApiUrl + "/CMD_API_SHOW_DOMAINS";
string response = getResponseFromServer(url, null);
response = HttpUtility.UrlDecode(response);
response = response.Replace("&", "");
response = response.Replace("list[]=", "|");
if (response.StartsWith("|")) {
response = response.Substring(1); // remove the first splitting char from the string
}
string[] domains = response.Split('|');
return domains;
}
public static bool createVirtualHosting(string domainName) {
if (isDomainExistant(domainName)) { // kill it the hard way.
throw new Exception("WmDirectAdminApi: Domain "+domainName+" already exists on server.");
}
// from here I assume that it is safe to continue creating an domain with FTP:
string createDomainUrl = serverApiUrl + "/CMD_API_DOMAIN";
List createDomainVariables = new List();
createDomainVariables.Add(new PostVariable("action", "create"));
createDomainVariables.Add(new PostVariable("domain", domainName));
createDomainVariables.Add(new PostVariable("ubandwidth", "unlimited"));
createDomainVariables.Add(new PostVariable("uquota", "uquota"));
createDomainVariables.Add(new PostVariable("cgi", "OFF"));
createDomainVariables.Add(new PostVariable("ssl", "OFF"));
createDomainVariables.Add(new PostVariable("php", "ON"));
string createDomainResponse = getResponseFromServer(createDomainUrl, createDomainVariables);
if (createDomainResponse.StartsWith("error=0")) { // error=0 is DirectAdmin's way of telling that it is OKAY
return true;
} else {
return false;
}
}
public static long getVirtualHostingUsage(string domainName) {
string domainsUrl = serverApiUrl + "/CMD_API_SHOW_USER_DOMAINS?user=lemmid";
string response = getResponseFromServer(domainsUrl,null);
int domainIndex = response.IndexOf(domainName);
if (domainIndex > -1) {
string data = response.Substring(domainIndex);
int nextDomainIndex = data.IndexOf("&");
if (nextDomainIndex == -1) {
nextDomainIndex = data.Length;
}
data = data.Substring(0, nextDomainIndex);
string[] dataValues = data.Split(':');
string valueAsString = dataValues[2];
double valueInMb = double.Parse(valueAsString,usCulture);
double valueInBytes = valueInMb * 1024 * 1024;
long valueAsLong = (long)Math.Round(valueInBytes);
return valueAsLong;
} else {
return -1;
}
}
public static bool removeVirtualHosting(string domainName) {
string deleteDomainUrl = serverApiUrl + "/CMD_API_DOMAIN";
List domainVariables = new List();
domainVariables.Add(new PostVariable("action", "delete"));
domainVariables.Add(new PostVariable("delete", domainName));
domainVariables.Add(new PostVariable("domain", domainName));
domainVariables.Add(new PostVariable("select0", domainName));
domainVariables.Add(new PostVariable("confirmed", "true"));
string domainResponse = getResponseFromServer(deleteDomainUrl, domainVariables);
if (domainResponse.StartsWith("error=0")) { // error=0 is DirectAdmin's way of telling that it is OKAY
return true;
} else {
return false;
}
}
public static bool removeFtpAccount(string domainName) {
string removeFtpUrl = serverApiUrl + "/CMD_API_FTP";
string ftpPassword = FtpPasswordGenerator.getRandomPassword();
List ftpVariables = new List();
ftpVariables.Add(new PostVariable("action", "delete"));
ftpVariables.Add(new PostVariable("domain", domainName));
ftpVariables.Add(new PostVariable("select0", "ftp"));
string ftpResponse = HttpUtility.UrlDecode(getResponseFromServer(removeFtpUrl, ftpVariables));
if (ftpResponse.StartsWith("error=0")) {
return true;
} else {
return false;
}
}
public static bool setFtpAccountPassword(string domainName, string newPassword) {
string modifyFtpUrl = serverApiUrl + "/CMD_API_FTP";
List ftpVariables = new List();
ftpVariables.Add(new PostVariable("action", "modify"));
ftpVariables.Add(new PostVariable("domain", domainName));
ftpVariables.Add(new PostVariable("user", "ftp")); // will end up like ftp@domainname.tld
ftpVariables.Add(new PostVariable("type", "custom"));
ftpVariables.Add(new PostVariable("custom_val", "/home/lemmid/domains/" + domainName + "/public_html"));
ftpVariables.Add(new PostVariable("passwd", newPassword));
ftpVariables.Add(new PostVariable("passwd2", newPassword));
string ftpPasswordResponse = HttpUtility.UrlDecode(getResponseFromServer(modifyFtpUrl, ftpVariables));
if (ftpPasswordResponse.StartsWith("error=0")) {
return true;
} else {
return false;
}
}
public static FtpCredentials createFtpAccount(string domainName) {
string createFtpUrl = serverApiUrl + "/CMD_API_FTP";
string ftpPassword = FtpPasswordGenerator.getRandomPassword();
List createFtpVariables = new List();
createFtpVariables.Add(new PostVariable("action", "create"));
createFtpVariables.Add(new PostVariable("domain", domainName));
createFtpVariables.Add(new PostVariable("user", "ftp")); // will end up like ftp@domainname.tld
createFtpVariables.Add(new PostVariable("type", "custom"));
createFtpVariables.Add(new PostVariable("custom_val", "/home/lemmid/domains/" + domainName + "/public_html"));
createFtpVariables.Add(new PostVariable("passwd", ftpPassword));
createFtpVariables.Add(new PostVariable("passwd2", ftpPassword));
string createFtpResponse = HttpUtility.UrlDecode(getResponseFromServer(createFtpUrl, createFtpVariables));
if (createFtpResponse.StartsWith("error=0")) {
FtpCredentials returnCredentials = new FtpCredentials("ftp@" + domainName, ftpPassword);
return returnCredentials;
}
return null; // in case of error
}
public static bool isDomainExistant(string domainName) {
string[] existingDomains = getVirtualHostingDomainNames();
foreach (string existingDomain in existingDomains) {
if (existingDomain.Equals(domainName)) {
return true;
}
}
return false;
}
public static string getResponseFromServer(string url, List postVariables) {
WebRequest request = WebRequest.Create(url);
string usernamePassword = username + ":" + password;
CredentialCache credentialCache = new CredentialCache();
credentialCache.Add(new Uri(serverApiUrl), "Basic", new NetworkCredential(username, password));
request.Credentials = credentialCache;
request.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(new ASCIIEncoding().GetBytes(usernamePassword)));
if (postVariables != null) {
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
string postString = "";
foreach (PostVariable variable in postVariables) {
postString += HttpUtility.UrlEncode(variable.Name) + "=" +
HttpUtility.UrlEncode(variable.Value) + "&";
}
byte[] postBytes = Encoding.ASCII.GetBytes(postString);
request.ContentLength = postBytes.Length;
Stream postStream = request.GetRequestStream();
postStream.Write(postBytes, 0, postBytes.Length);
postStream.Close();
} else {
request.Method = "GET";
}
WebResponse response = request.GetResponse();
Stream receiveStream = response.GetResponseStream();
StreamReader reader = new StreamReader(receiveStream, Encoding.UTF8);
string content = reader.ReadToEnd();
return content;
}
}
public class PostVariable{
protected string name;
protected string value;
public PostVariable(string name, string value){
this.name = name;
this.value = value;
}
public string Name{
get { return name;}
set { name = value;}
}
public string Value{
get { return this.value;}
set { this.value = value; }
}
}
public class FtpCredentials {
protected string ftpUsername;
protected string ftpPassword;
public FtpCredentials(string ftpUsername, string ftpPassword) {
this.ftpUsername = ftpUsername;
this.ftpPassword = ftpPassword;
}
public string FtpUsername {
get { return ftpUsername; }
set { ftpUsername = value; }
}
public string FtpPassword {
get { return ftpPassword; }
set { ftpPassword = value; }
}
}
}