|
I have been looking for the anwer to this question for days now. I found that their is very little on smart card implementaion for C# but from alot of research I and alot of playing around I have finialy solved the question. Below is a working example of my smart card class
SmartCard.cs file
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Security.Permissions;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Windows.Forms;
using System.Diagnostics;
using System.IO;
using System.Security;
using System.ComponentModel;
namespace SmartCardApp
{
public class SmartCard
{
internal static int CertCredential = 1;
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool CredMarshalCredential(
int credType,
IntPtr credential,
out IntPtr marshaledCredential
);
[DllImport("user32.dll")]
private static extern IntPtr GetDC(IntPtr hWnd);
[StructLayout(LayoutKind.Sequential)]
internal struct CERT_CREDENTIAL_INFO
{
public uint cbSize;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
public byte[] rgbHashOfCert;
}
public static string pin = null;
public static X509Certificate2 cert = null;
public struct UserLoginInfo
{
public string domain;
public string username;
public SecureString password;
}
public void SmartCardLogon()
{
cert = GetClientCertificate();
Form login = new Form();
login.Height = 100;
login.Width = 100;
login.MaximizeBox = false;
login.MinimizeBox = false;
login.ControlBox = false;
login.Name = "frmCaCLogin";
login.Text = "Enter Pin";
TextBox TextBox1 = new TextBox();
TextBox1.Name = "txtCaCLogin";
TextBox1.PasswordChar = '*';
login.Controls.Add(TextBox1);
Button b = new Button();
b.FlatStyle = FlatStyle.Flat;
b.Text = "Login";
b.Name = "butCacLogin";
b.Click += new EventHandler(b_Click);
login.Controls.Add(b);
login.Controls["butCacLogin"].Top += 20;
login.TopMost = true;
login.ShowDialog();
}
void b_Click(object sender, EventArgs e)
{
pin = Application.OpenForms["frmCaCLogin"].Controls["txtCaCLogin"].Text;
Application.OpenForms["frmCaCLogin"].Hide();
if (cert != null)
{
UserLoginInfo user = Login(cert);
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = Application.ExecutablePath;
psi.UserName = user.username;
psi.Password = user.password;
psi.UseShellExecute = false;
Process.Start(psi);
Application.Exit();
}
}
public UserLoginInfo Login(X509Certificate2 cert)
{
UserLoginInfo uli = new UserLoginInfo();
CERT_CREDENTIAL_INFO certInfo =
new CERT_CREDENTIAL_INFO();
certInfo.cbSize = (uint)Marshal.SizeOf(typeof(CERT_CREDENTIAL_INFO));
certInfo.rgbHashOfCert = cert.GetCertHash();
int size = Marshal.SizeOf(certInfo);
IntPtr pCertInfo = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(certInfo, pCertInfo, false);
IntPtr marshaledCredential = IntPtr.Zero;
bool result =
CredMarshalCredential(CertCredential,
pCertInfo,
out marshaledCredential);
string domainName = string.Empty;
string userName = string.Empty;
string password = string.Empty;
if (result)
{
domainName = String.Empty;
userName = Marshal.PtrToStringUni(marshaledCredential);
password = pin;
}
SecureString sc = new SecureString();
foreach (char c in pin)
{
sc.AppendChar(c);
}
uli.domain = Environment.UserDomainName;
uli.username = userName;
uli.password = sc;
return uli;
}
public static X509Certificate2 GetClientCertificate()
{
WindowsImpersonationContext impersonationContext = null;
IntPtr ptr = IntPtr.Zero;
X509Certificate2 certificate = null;
X509Certificate t = null;
var store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
try
{
store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
if (store.Certificates != null && store.Certificates.Count > 0)
{
if (store.Certificates.Count == 1)
{
certificate = store.Certificates[0];
}
else
{
var certificates = X509Certificate2UI.SelectFromCollection(store.Certificates, "Digital Certificates", "Select a certificate from the following list:", X509SelectionFlag.SingleSelection, ptr);
if (certificates != null && certificates.Count > 0)
certificate = certificates[0];
}
}
}
finally
{
store.Close();
}
return certificate;
}
}
this is the code i use for the smartcard login button
form1.cs file
just ad a button to a form call it butCacLogin put all the code from the class above into a new class called SmartCard.cs then just run the code.
private void butCacLogin_Click(object sender, EventArgs e)
{
this.Hide();
SmartCard sc = new SmartCard();
sc.SmartCardLogon();
this.Close();
}
The form for the pin could use some decorating but this works like a charm. At first I tried to use wiondws LogonUser method and using impersantation however when trying to start the process back up with the new credentials it was getting either directory not found or file not found. I then decided to just pass the credentials I recived back from the cert directly to the process and that worked perfectly. I looked for days never found full code for this only bits and pieaces of code and never a good working example.
The reason I started this up is because you can't do a runas on a one click application by right clicking it. Then I figured out how to pass the username and password to the process but our network is cac enforced. Then I decided to find a way to enable the process to start with cac credentials. I hope this helps somone out because this is probally the only place you can find the full working code for C# every other place i looked was just pieaces of code.
modified 21-May-14 17:58pm.
|
|
|
|
|
This is the start of an interesting article (I have seen less work go into some). Expand on the reasons for your decisions, discuss the requirements, add a few screen shots and you will do the community a service by publishing this as an article.
The effort of publishing is rewarded by you getting a better understanding as you try and explain it to others. Oh and Author points of course.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
Very interesting but this forum is really not the place; you should write an article about it and publish it that way.
|
|
|
|
|
sorry for putting it in the wrong area im am kind of new to this site was not sure where to put it. I look at making this a article instead and remove it from the forums.
|
|
|
|
|
Steven Richardson wrote: im am kind of new to this site was not sure Always worth looking at the Readmes, Howtos and FAQs first.
|
|
|
|
|
I created a article on this topic I am unable to remove the thread if possible could you remove it.
|
|
|
|
|
The thread is permanent now; don't worry about it.
|
|
|
|
|
hi there i have a problem with my 2d character again...i fixed my previous problems but the new problem is that,that i cant make my character punchin...he walks,he jumps pretty well but i'm in some problem with punchin movement or anything like this...i made a punch animation and i made a transation to the idle and from idle to puch in the animator window...and also i made a trigger parameter but my code dosent work...may be the code i wrote is completley worng...if thats wrong please tell me what shout id do? thanks
using UnityEngine;
using System.Collections;
public class ScrorpionControllerScript : MonoBehaviour
{
public float maxSpeed = 10f;
bool facingRight = true;
Animator anim;
bool grounded = false;
public Transform groundCheck;
float groundRadius = 0.2f;
public LayerMask whatIsGround;
float jumpTime, jumpDelay = 0.2f;
bool jumped;
float punchTime, punchDelay = .5f;
bool punch;
void Start ()
{
anim = GetComponent<Animator> ();
}
void FixedUpdate ()
{
grounded = Physics2D.OverlapCircle (groundCheck.position, groundRadius, whatIsGround);
anim.SetBool ("Ground", grounded);
anim.SetFloat ("vSpeed", rigidbody2D.velocity.y);
anim.SetBool ("Ground", grounded);
float move = Input.GetAxis ("Horizontal");
anim.SetFloat ("wa", Mathf.Abs (move));
rigidbody2D.velocity = new Vector2(move * maxSpeed, rigidbody2D.velocity.y);
if(move > 0 &&! facingRight)
Flip ();
else if (move < 0 && facingRight)
Flip ();
}
void Update()
{
if(Input.GetKeyDown (KeyCode.Space) && grounded)
{
rigidbody2D.AddForce(transform.up * 275f);
jumpTime = jumpDelay;
anim.SetTrigger("Jump");
jumped = true;
}
jumpTime -= Time.deltaTime;
if (jumpTime <= 0 && grounded && jumped)
{
anim.SetTrigger ("Land");
jumped = false;
}
if (Input.GetKeyDown (KeyCode.R));
{
punchTime = punchDelay;
anim.SetTrigger("punch");
punch = true;
}
}
void Flip()
{
facingRight = !facingRight;
Vector3 theScale = transform.localScale;
theScale.x *= -1;
transform.localScale = theScale;
}
}
|
|
|
|
|
You posted the same thing 7 hours ago in QA: unity 2D C# coding problem[^] and were told you didn't ask an actual question.
Please don't post the same thing in multiple places: it duplicates work and that annoys people.
Those who fail to learn history are doomed to repeat it. --- George Santayana (December 16, 1863 – September 26, 1952)
Those who fail to clear history are doomed to explain it. --- OriginalGriff (February 24, 1959 – ∞)
|
|
|
|
|
When I have the following definitions:
public class CMsg
{
protected int m_Id;
}
public class CMsgTx : CMsg
{
public string m_Dst;
}
To be used by:
public abstract class CNet
{
abstract public int SendMsg(ref CMsg oMsg);
}
public class CNetSend : CNet
{
override public int SendMsg(ref CMsg oMsg)
{
CMsgTx oTxMsg = oMsg as CMsgTx;
return 1;
}
}
I getting compiler error when trying to call SendMsg:
{...
CMsgTx oMsg = new CMsgTx();
CNetSend oSender = new CNetSend()
oSender.SendMsg(ref oMsg);
...}
My question is how to convert CMsgTx.oMsg to CMsg when calling SendMsg,
I thought that the compiler would do it...
|
|
|
|
|
You can't do that with ref parameters.
Why not? Simple: you could replace the instance you pass in with a completely different type also derived from the same base type - which could mean that the outside world ends up with a CMsgTx variable referencing a CMsgBananaSplit instance - which doesn't support half the properties of CMsgTx, but does support the IceCream property and the GetNuts method - and so forth.
You can only pass a reference through if it is of the exact same type as the methdo declaration, not a derived type at all.
Those who fail to learn history are doomed to repeat it. --- George Santayana (December 16, 1863 – September 26, 1952)
Those who fail to clear history are doomed to explain it. --- OriginalGriff (February 24, 1959 – ∞)
|
|
|
|
|
What about out parameters,
in case of:
public abstract class CNet
{
abstract public int SendMsg(out CMsg oMsg);
}
public class CNetRx : CNet
{
override public int SendMsg(out CMsg oMsg)
{
CMsgTx oTxMsg = new CMsgTx();
oMsg = (CMsg)oTxMsg ;
return 1;
}
}
and the program:
CMsg oM;
CNetRx oNetRx = new CNetRx();
oNetRx.SendMsg(out oM);
CMsgTx oMsgTx = oM as CMsgTx;
is there also loss of information?
Do you suggest other 'design' for CNet and CMsg classes?
|
|
|
|
|
No - because what you pass through is a valid CMsg - it's derived from it, and the variable you pass into is a CMsg, not a derived class. So to use it as an instance of CMsgTx you have to cast it - as your code does - and a derived class instance that doesn't include CMsgTx will not cast: the as will return null.
Those who fail to learn history are doomed to repeat it. --- George Santayana (December 16, 1863 – September 26, 1952)
Those who fail to clear history are doomed to explain it. --- OriginalGriff (February 24, 1959 – ∞)
|
|
|
|
|
Why does it need to be a ref parameter?
namespace ConsoleApplication379
{
class ReferenceTest
{
public string Bla { get; set; }
}
class Program
{
static void Main(string[] args)
{
var a = new ReferenceTest() { Bla = "Test" };
change(a);
Console.WriteLine(a.Bla);
Console.ReadLine();
}
static void change(ReferenceTest whichOne)
{
whichOne.Bla = "Hello World";
}
}
} I'm asking because it makes more sense to use on a value-type, not on a pointer.
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
Why MVC best from Asp.Net while less work in asp.net as compare to MVC.
|
|
|
|
|
Did you read your question before posting? It's a good practice...
I'm not questioning your powers of observation; I'm merely remarking upon the paradox of asking a masked man who he is. (V)
|
|
|
|
|
Sorry , I got answer of my question.
|
|
|
|
|
It depends what you are doing - to hack together a simple ASP.NET winforms style web app, then asp.net is probably going to be easier. Where MVC wins is where you actually want to create websites, or sites with more modern features (for example AJAX calls, exposing a REST API), then MVC3 wins IMO.
The other thing you have to take into account is the learning curve: if you've been an asp.net "forms" developer for 2 years and you switch to MVC, then you're already 2-years behind more or less, and you have to stop using a lot of techniques you've become used to.
So the answer is, if you've gained a similar amount of experience/expertise in both technologies and one has taken more effort than the other one, you've chosen the wrong tech.
|
|
|
|
|
Thanks a lot ,
|
|
|
|
|
What is Extension Method in C# and when i can use it ?
|
|
|
|
|
|
An extension method is a piece of code that allows you to extend a type with custom functionality. This feature was introduced alongside LINQ. Suppose you wanted to add the ability to check whether or not an integer was within a certain range, you would declare a static method inside a static class (this is required for extension methods), that passed in the parameter in a special way. Here's this example
public static class IntegerExtensions
{
public static bool Between(this int value, int startRange, int endRange)
{
return value >= startRange && value <= endRange;
}
} To call this you would do something like this:
int checker = 10;
if (checker.Between(0, 50)
{
Console.WriteLine("I'm in the range");
} Now, if you want to use the extension method, you have to make sure that the namespace for the static class is included in the file that you are calling the extension from. Also, there's nothing to stop you writing this code as well
if (IntegerExtensions.Between(checker, 0, 50)) Ultimately they resolve to the same thing.
|
|
|
|
|
What sort of pond life would downvote such an excellent answer to a question? Compensation provided.
|
|
|
|
|
Thanks. I have to admit, I was surprised by the vote as I thought I'd given a clear enough start to get someone on the way with extension methods. Oh well
|
|
|
|
|
Hi
I have about 1000 2d points that I draw a ClosedCurve on bitmap then on picturbox, but I want saving a few points from this 1000 points that are necessery to drawing previous ClosedCurve or shape.
Thanks
|
|
|
|