Create virtual network interface programmatically - c#

Is it possible to add a virtual network interface with Java or C#. I need to set a bunch of IPs to my computer for a data mining app and I don't have enought NICs (I don't want to buy more yet).
I need full control of virtual cards from the app (create, delete, set IP, maybe redirect traffic).

I am not sure you have a pure Java solution for this.
You have several alternatives.
1. Use a script that will do that for you, writing this solution in perl\shell will be 4-5 lines.
2. You can open a ssh connection to your machine and run the commands from Java.
I have such utility that uses trilead-ssh2.
To get it using maven you can use:
<dependency>
<groupId>com.trilead</groupId>
<artifactId>trilead-ssh2</artifactId>
<version>build213-svnkit-1.3-patch</version>
</dependency>
For example, this way you should open a connection:
public static Connection newConnectionWithPassword(String host, String username, String passwd) {
Connection newConn = new Connection(host);
try {
newConn.connect(); // Ignoring ConnectionInfo returned value.
newConn.authenticateWithPassword(username, passwd);
return newConn;
} catch (IOException ioe) {
newConn.close();
ioe.printStackTrace();
return null;
}
}
Then to run your command you can :
this.session = conn.openSession();
this.session.execCommand(this.cmd);
You can use an OS command to create your virtual interfaces from java now.
BTW,
You can test the results using NetworkInterface.class , that can query a netweork interface on your machine.
Good luck.

Related

EzAPI OLEDB Connection with SQL Authentication

I'm trying to create an SSIS package using EzAPI 2012. The templates and tutorials that I've found works fine but I am not able to find anything on creating a connection to a OLEDB with SQL Authentication (username and password). Here's part of code that I'm using to create OLEDB connection:
// Creating a connection to the database:
EzSqlOleDbCM srcConn = Activator.CreateInstance(typeof(EzSqlOleDbCM), new object[] { package }) as EzSqlOleDbCM;
srcConn.SetConnectionString(_CL_SourceServerName, _CL_SourceDBName);
srcConn.Name = "SourceDB";
EzSqlOleDbCM destConn = Activator.CreateInstance(typeof(EzSqlOleDbCM), new object[] { package }) as EzSqlOleDbCM;
destConn.SetConnectionString(_CL_DestServerName, _CL_DestDBName);
destConn.Name = "DestDB";
The names with "CL" in the beginning are variables. The EzSqlOleDbCM function does not have parameters for username and password.
Thanks,
EzApi is great for the problems it solves. This is one of the many cases where it falls short. You can see in the source code they have hard coded the connection manager to use SSPI
/// <summary>
/// OleDb connection manager for SQL Server
/// </summary>
public class EzSqlOleDbCM : EzOleDbConnectionManager
{
public EzSqlOleDbCM(EzPackage parent) : base(parent) { }
public EzSqlOleDbCM(EzPackage parent, ConnectionManager c) : base(parent, c) { }
public EzSqlOleDbCM(EzPackage parent, string name) : base(parent, name) { }
public EzSqlOleDbCM(EzProject parentProject, string streamName) : base(parentProject, streamName) { }
public EzSqlOleDbCM(EzProject parentProject, string streamName, string name) : base(parentProject, streamName, name) { }
public void SetConnectionString(string server, string db)
{
ConnectionString = string.Format("provider=sqlncli11;integrated security=sspi;database={0};server={1};OLE DB Services=-2;Auto Translate=False;Connect Timeout=300;",
db, server);
}
}
What can be done?
Modify the source code to accommodate userids and passwords
Do as much as you can in EzApi and then revert to using the base SSIS object model - See the LoadFromXML portion but since this is connection manager, that will pretty much be everything
I don't think you can fake your way through it by adding Expressions to the connection manager itself as when it attempts to set metadata during development/object creation, the expressions won't yet be active
Give up on EzAPI - I know I have. I find using Biml far easier for the programmatic creation of SSIS packages. And it's supported whereas EzAPI appears to be abandoned.
Here is the source code for the connection managers in EzAPI. Based on that, EzSqlOleDbCM (which is what you are using) extends EzOleDbConnectionManager which in turn extends EzConnectionManager
You are using SetConnectionString method on EzSqlOleDbCm; which unfortunately is hard coded to use only the Windows Auth.
So here are the options I would try:
Option 1:
EzConnectionManager exposes a property called ConnectionString and has a setter; so you can directly assign the connection string (with your user name and password) using this property (and avoid the SetConnectionString method call). For example:
srcConn.ConnectionString = #"Provider=my_oledb_provider;Data Source=myServerAddress;Initial Catalog=myDataBase; User Id=myUsername;Password=myPassword";
Option 2:
Additionally, EzOleDbConnectionManager exposes the UserName and Password properties; so you can use these properties also to specify your username and password. However if you this, then you cannot use the SetConnectionString method; cos that is hard coded to use Windows Auth, which means you will have to overwrite it again using previous option.
srcConn.UserName = "my_user_name";
srcConn.Password = "my_password";
Option 3:
If you are using the EzAPI source code directly in your project, I would add another convenience method called SetConnectionString, but one which accepts a user name and password.
public void SetSqlAuthConnectionString(string server, string db, string user, string pwd)
{
// Notice that we are just setting the ConnectionString property.
ConnectionString =string.Format("Provider=my_oledb_provider;Data Source={0};Initial Catalog={1};User Id={2};Password={3}", server, db, user, pwd
};
Then you can use as follows:
srcConn.SetSqlAuthConnectionString(myServer, myDB, userName, password);
Alternatively, at an even higher level: I would also give Biml a shot. If that serves your need well and good. Also, I wrote a library similar to EzApi called Pegasus; which you can find here. You can look at the source code and re-use it or use the code as is. Now both EzAPI and Pegasus are wrappers around the SSIS object model API. Thus, you can use the SSIS API directly; but using it directly would be a pain since you will write a lot of boiler plate code and repeat your code. You are better off writing your own wrapper against the official API; or use something like EzAPI or Pegasus.
If SSIS is your day job and you create a lot of packages according to some patterns, then I would recommend you definitely look into package automation. The development and testing time savings are huge and huge and huge. If you are unwilling to use 3rd party libraries (like EzApi or Pegasus), I would recommend you to take a look at the source code of those libraries and roll your own; or Biml.
Let me know if you need any guidance/comments on package automation.

Run script on machine from other machine in C#

I'm writing a Web Service (WCF) for my work and I'm looking for a way to
run script on demand on other machine.
We got machines that we connect from RDC, and I want to run a script on it
from another C# program.
Also, I can't seem to find a way to run an executable file on another machine from C#.
The reason why you can't find a part of the .Net framework that lets you run executables on another machine is because there isn't one.
If you want a straightfoward way of running an executable on a remote machine then you may be interested in PsExec (a Sysinternals tool released by Micrososft).
this is possible using WMI via C# (see http://www.codeproject.com/KB/cs/Remote_Process_using_WMI_.aspx) or via commandline using http://technet.microsoft.com/en-us/sysinternals/bb897553.aspx ... but it is something you usually should NOT do - it creates several security issues to deal with...
EDIT - WMI with User/PW:
connectionoptions gives you the possibility to supply a UserName + Password - see http://msdn.microsoft.com/en-us/library/system.management.connectionoptions.aspx
I know this is an old post, but I would like to add that it is certainly possible to run a remote executable without PsExec which many virus software flags as problematic. Also most sys admins don't want PsExec on their web servers. And, running a remote executable via mapped drive or UNC does not mean that you have the license installed, so it may fail (or run a demo version) depending on the software.
The key is to wrap the System.Diagnostics.Process steps in a WCF service. Here is a partial example...
{
// Define a service contract.
[ServiceContract(Namespace = "http://MyDataServices.foo.com")]
public interface IDataService
{
[OperationContract]
bool ProcessStatTransfer(MemoryStream inputCommands, string inputName);
}
// Implement the IDataService service contract in a service class.
public class DataService : IDataService
{
// Implement the IDataService methods.
public bool ProcessStatTransfer(MemoryStream inputCommands, string inputName)
{
try
{
// StatTransferLocation is C:\Program Files\StatTransfer12-64\st.exe
// on the machine that hosts the service
string m_stattransfer_loc = ConfigurationManager.AppSettings["StatTransferLocation"].ToString();
string m_stattransfer_file = ConfigurationManager.AppSettings["CommandFiles"].ToString() + inputName;
using (FileStream m_fsfile = new FileStream(m_stattransfer_file, FileMode.Create, FileAccess.Write))
{
inputCommands.WriteTo(m_fsfile);
}
ProcessStartInfo processInfo = new ProcessStartInfo("\"" + m_stattransfer_loc + "\"");
processInfo.Arguments = "\"" + m_stattransfer_file + "\"";
processInfo.UseShellExecute = false;
processInfo.ErrorDialog = false;
processInfo.CreateNoWindow = true;
Process batchProcess = new Process();
batchProcess.StartInfo = processInfo;
batchProcess.Start();
return true;
}
catch
{
return false;
}
}
.....
Then you add a service reference and invoke the method. No mappings, PsExec, or WMI. It is a pure C# solution.

I'd like to run a command over ssh from a windows box running using c#

Note that this has to be on a windows box as I am using c# to access information about windows
(I need information from both a windows box and a linux box, plus I think that making a program/script that runs without gui and accesses windows from a linux box without user intervention would be more difficult, if this is not true please tell me, I would love to do get this running on *nix with only the part that access windows info running on windows).
There is a nice c# api to get this information from windows, on *nix its simple enough to run a command and parse the output to my needs.
There doesn't seem to much decent advice about using ssh from c# out there, sharpSSH and Granados seem to have not been updated for years, are they decent? should I be possible worried about security issues?
(the info I'm retrieving isn't sensitive but if the ssh implementation might have unpatched security flaws(if they haven't been updated for years) I'm worried about someone stealing my credentials.
Are there any other decent c# ssh libraries. If the command output is simple should I just run plink/putty(is it difficult to run a windows cmd shell for plink, and capture output(and is there a way to do it without the shell popping up)?
P.S. while the commercial library seems nice I prefer something free (as in cost and free in source if possible).
Sample Code
There are several commercial SSH client libraries for C#. Following code shows how to connect to a *nix box, run a command and read the response using our Rebex SSH Shell.
// create client, connect and log in
Ssh client = new Ssh();
client.Connect(hostname);
client.Login(username, password);
// run the 'uname' command to retrieve OS info
string systemName = client.RunCommand("uname -a");
// display the output
Console.WriteLine("OS info: {0}", systemName);
client.Disconnect();
For advanced scenarios (such as interactive commands) see SSH Shell Tutorial.
References & Stability
You might be already using Rebex SSH core library without knowing about it. The Rebex SFTP (which uses this SSH lib as a transport layer) is used by Microsoft in several products including Expression Web and Visual Studio 2010. The Rebex SSH Shell is 'just' another layer on top of it (most notable addition is a terminal emulator).
You can download a trial from http://www.rebex.net/ssh-shell.net/download.aspx. Support forum uses engine very similar to this site and runs on http://forum.rebex.net/
Disclaimer: I am involved in development of Rebex SSH
It is quite easy to call plink without the shell popping up.
The trick to not show a window is to set ProcessStartInfo.CreateNoWindow = true.
Add some error handling to this and you're done.
--- PlinkWrapper.cs ---
using System.Collections.Generic;
using System.Diagnostics;
namespace Stackoverflow_Test
{
public class PlinkWrapper
{
private string host { get; set; }
/// <summary>
/// Initializes the <see cref="PlinkWrapper"/>
/// Assumes the key for the user is already loaded in PageAnt.
/// </summary>
/// <param name="host">The host, on format user#host</param>
public PlinkWrapper(string host)
{
this.host = host;
}
/// <summary>
/// Runs a command and returns the output lines in a List<string>.
/// </summary>
/// <param name="command">The command to execute</param>
/// <returns></returns>
public List<string> RunCommand(string command)
{
List<string> result = new List<string>();
ProcessStartInfo startInfo = new ProcessStartInfo("plink.exe");
startInfo.UseShellExecute = false;
startInfo.RedirectStandardOutput = true;
startInfo.CreateNoWindow = true;
startInfo.Arguments = host + " " + command;
using (Process p = new Process())
{
p.StartInfo = startInfo;
p.Start();
while (p.StandardOutput.Peek() >= 0)
{
result.Add(p.StandardOutput.ReadLine());
}
p.WaitForExit();
}
return result;
}
}
}
--- END PlinkWrapper.cs ---
Call it like
PlinkWrapper plink = new PlinkWrapper("albin#mazarin");
foreach (var str in plink.RunCommand("pwd"))
Console.WriteLine("> " + str);
and the output will be like
> /home/albin
The nice thing with plink is that it is well proven and integrates well with pageant.
I used SharpSsh lib to make an asynchronous directory sync program between linux and windows boxes (i choosed sftp for secure file tranfer). Remained unchanged for years doesn't mean it is unsecure.
it is really easy to use:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Tamir.SharpSsh;
namespace sftpex
{
class Program
{
static void Main(string[] args)
{
try
{
SshExec exec = new SshExec(ipAddress, username, password);
Console.Write("Connecting...");
exec.Connect();
Console.WriteLine("OK");
if (exec.Connected)
Console.WriteLine(exec.Cipher);
while (true)
{
Console.Write("Enter a command to execute ['Enter' to cancel]: ");
string command = Console.ReadLine();
if (command == "") break;
string output = exec.RunCommand(command);
string[] m = output.Split('\n');
for(int i=0; i<m.Length; i++)
Console.WriteLine(m[i]);
}
Console.Write("Disconnecting...");
exec.Close();
Console.WriteLine("OK");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
}
If you're not averse to interop with C libs, I believe OpenSSH is one of the best libraries available for the job.
I used SharpSSH in the past to execute commands on a Linux box. There are quite a few bugs, and I had to modify the code to fix some of them, but eventually it kinda worked...
There is a commercial software IP*Works SSH which can do the job.

SSH / SFTP connection issue using Tamir.SharpSsh

This is my code to connect and send a file to a remote SFTP server.
public static void SendDocument(string fileName, string host, string remoteFile, string user, string password)
{
Scp scp = new Scp();
scp.OnConnecting += new FileTansferEvent(scp_OnConnecting);
scp.OnStart += new FileTansferEvent(scp_OnProgress);
scp.OnEnd += new FileTansferEvent(scp_OnEnd);
scp.OnProgress += new FileTansferEvent(scp_OnProgress);
try
{
scp.To(fileName, host, remoteFile, user, password);
}
catch (Exception e)
{
throw e;
}
}
I can successfully connect, send and receive files using CoreFTP. Thus, the issue is not with the server. When I run the above code, the process seems to stop at the scp.To method. It just hangs indefinitely.
Anyone know what might my problem be? Maybe it has something to do with adding the key to the a SSH Cache? If so, how would I go about this?
EDIT: I inspected the packets using wireshark and discovered that my computer is not executing the Diffie-Hellman Key Exchange Init. This must be the issue.
EDIT: I ended up using the following code. Note, the StrictHostKeyChecking was turned off to make things easier.
JSch jsch = new JSch();
jsch.setKnownHosts(host);
Session session = jsch.getSession(user, host, 22);
session.setPassword(password);
System.Collections.Hashtable hashConfig = new System.Collections.Hashtable();
hashConfig.Add("StrictHostKeyChecking", "no");
session.setConfig(hashConfig);
try
{
session.connect();
Channel channel = session.openChannel("sftp");
channel.connect();
ChannelSftp c = (ChannelSftp)channel;
c.put(fileName, remoteFile);
c.exit();
}
catch (Exception e)
{
throw e;
}
Thanks.
I use Tamir.SharpSSH - latest version 1.1.1.13
This has a class SFTP. You can use this class directly to do SFTP instead of using JSch, Session class.
Quick Sample here:
127.0.0.1 - Server IP
/SFTPFolder1/SFTPFolder2 - Server Location Where I want my files to go
Sftp sftpClient = new Sftp("127.0.0.1", "myuserName", "MyPassword");
sftpClient.Connect();
sftpClient.Put(#"C:\Local\LocalFile.txt", "/SFTPFolder1/SFTPFolder2");
Let me know if you have any issues.
Without looking at your log files it is hard to tell what the issue is.
However keep in mind that SCP is not SFTP - they are completely different protocols that run over SSH. It is possible that your SFTP does not actually support SCP - not all SFTP servers do. CoreFTP may be using SFTP.
Our commercial package, edtFTPnet/PRO, might also be worth trying, if only as an alternative to try to get a different client working against your server.

Use C# to interact with Windows Update

Is there any API for writing a C# program that could interface with Windows update, and use it to selectively install certain updates?
I'm thinking somewhere along the lines of storing a list in a central repository of approved updates. Then the client side applications (which would have to be installed once) would interface with Windows Update to determine what updates are available, then install the ones that are on the approved list. That way the updates are still applied automatically from a client-side perspective, but I can select which updates are being applied.
This is not my role in the company by the way, I was really just wondering if there is an API for windows update and how to use it.
Add a Reference to WUApiLib to your C# project.
using WUApiLib;
protected override void OnLoad(EventArgs e){
base.OnLoad(e);
UpdateSession uSession = new UpdateSession();
IUpdateSearcher uSearcher = uSession.CreateUpdateSearcher();
uSearcher.Online = false;
try {
ISearchResult sResult = uSearcher.Search("IsInstalled=1 And IsHidden=0");
textBox1.Text = "Found " + sResult.Updates.Count + " updates" + Environment.NewLine;
foreach (IUpdate update in sResult.Updates) {
textBox1.AppendText(update.Title + Environment.NewLine);
}
}
catch (Exception ex) {
Console.WriteLine("Something went wrong: " + ex.Message);
}
}
Given you have a form with a TextBox this will give you a list of the currently installed updates. See http://msdn.microsoft.com/en-us/library/aa387102(VS.85).aspx for more documentation.
This will, however, not allow you to find KB hotfixes which are not distributed via Windows Update.
The easiest way to do what you want is using WSUS. It's free and basically lets you setup your own local windows update server where you decide which updates are "approved" for your computers. Neither the WSUS server nor the clients need to be in a domain, though it makes it easier to configure the clients if they are. If you have different sets of machines that need different sets of updates approved, that's also supported.
Not only does this accomplish your stated goal, it saves your overall network bandwidth as well by only downloading the updates once from the WSUS server.
If in your context you're allowed to use Windows Server Update Service (WSUS), it will give you access to the Microsoft.UpdateServices.Administration Namespace.
From there, you should be able to do some nice things :)
P-L right. I tried first the Christoph Grimmer-Die method, and in some case, it was not working. I guess it was due to different version of .net or OS architecture (32 or 64 bits).
Then, to be sure that my program get always the Windows Update waiting list of each of my computer domain, I did the following :
Install a serveur with WSUS (may save some internet bandwith) : http://www.microsoft.com/en-us/download/details.aspx?displaylang=en&id=5216
Add all your workstations & servers to your WSUS server
Get SimpleImpersonation Lib to run this program with different admin right (optional)
Install only the administration console component on your dev workstation and run the following program :
It will print in the console all Windows updates with UpdateInstallationStates.Downloaded
using System;
using Microsoft.UpdateServices.Administration;
using SimpleImpersonation;
namespace MAJSRS_CalendarChecker
{
class WSUS
{
public WSUS()
{
// I use impersonation to use other logon than mine. Remove the following "using" if not needed
using (Impersonation.LogonUser("mydomain.local", "admin_account_wsus", "Password", LogonType.Batch))
{
ComputerTargetScope scope = new ComputerTargetScope();
IUpdateServer server = AdminProxy.GetUpdateServer("wsus_server.mydomain.local", false, 80);
ComputerTargetCollection targets = server.GetComputerTargets(scope);
// Search
targets = server.SearchComputerTargets("any_server_name_or_ip");
// To get only on server FindTarget method
IComputerTarget target = FindTarget(targets, "any_server_name_or_ip");
Console.WriteLine(target.FullDomainName);
IUpdateSummary summary = target.GetUpdateInstallationSummary();
UpdateScope _updateScope = new UpdateScope();
// See in UpdateInstallationStates all other properties criteria
_updateScope.IncludedInstallationStates = UpdateInstallationStates.Downloaded;
UpdateInstallationInfoCollection updatesInfo = target.GetUpdateInstallationInfoPerUpdate(_updateScope);
int updateCount = updatesInfo.Count;
foreach (IUpdateInstallationInfo updateInfo in updatesInfo)
{
Console.WriteLine(updateInfo.GetUpdate().Title);
}
}
}
public IComputerTarget FindTarget(ComputerTargetCollection coll, string computername)
{
foreach (IComputerTarget target in coll)
{
if (target.FullDomainName.Contains(computername.ToLower()))
return target;
}
return null;
}
}
}

Categories

Resources