Can the same USM user be added with different set of authentication and privacy algorithms? - snmp4j

In my code, I am configuring the usm user and adding the user for SNMP
v3. I want to configure the user in a way that it will support the
below set of algorithms at the same time.
SHA-1 + AES128,
SHA-1 + DES,
MD5 + AES128,
MD5 + DES
Let's say the same usm user is capable of supporting these 4
combinations at the same time. Now, when I try from a management
console, I want to select any combination of the above 4 and the SNMP
Agent should work.
Note: I do not want to add new usm users. I want the same user to be
configured with the above 4 combinations at the same time.
UsmUser user = new UsmUser(new OctetString(m_usmUser),
snmpAuthenticationAlgorithm,
snmpAuthenticationPassword,
snmpPrivacyAlgorithm,
snmpPrivacyPassword);
usm.addUser(user.getSecurityName(), user.getLocalizationEngineID(), user);
Rather than the above, I want to user something like below.
UsmUser user = new UsmUser(new OctetString(m_usmUser),
AuthMD5.ID,
snmpAuthenticationPassword,
PrivDES.ID,
snmpPrivacyPassword);
usm.addUser(user.getSecurityName(), user.getLocalizationEngineID(), user);
user = new UsmUser(new OctetString(m_usmUser),
AuthMD5.ID,
snmpAuthenticationPassword,
PrivAES128.ID,
snmpPrivacyPassword);
usm.addUser(user.getSecurityName(), user.getLocalizationEngineID(), user);
user = new UsmUser(new OctetString(m_usmUser),
AuthSHA.ID,
snmpAuthenticationPassword,
PrivAES128.ID,
snmpPrivacyPassword);
usm.addUser(user.getSecurityName(), user.getLocalizationEngineID(), user);
user = new UsmUser(new OctetString(m_usmUser),
AuthSHA.ID,
snmpAuthenticationPassword,
PrivDES.ID,
snmpPrivacyPassword);
usm.addUser(user.getSecurityName(), user.getLocalizationEngineID(), user);

The SNMPv3 standard does not support more than one auth+priv combination per USM user within a USM configuration as defined RFC 3414. This limit is caused by the structure and indexing of the usmUserTable.
However, with SNMP4J you may defined more than one USM instance per agent and assign each USM instance its own usmUserTable instance and register each of that table instances within their own SNMPv3 context.
Although this would work, it might by easier to understand and implement using security protocol suffixes (or prefixes) in the SNMPv3 usernames like "myUser.AES128" vs. "myUser.DES", etc.

Related

StackService: Preempt user logins and assign roles and permissions on login

I'm looking for a way to assign Roles and Permissions to a user whose email I know but has not yet logged into my service. Auth is done using external auth providers (aad).
I played around with clearing the UserAuth and UserAuthDetails tables and then creating a bare minimum UserAuth entry that anticipates my login (id, email, username and dates) but upon signing in another UserAuth entry was created to go along with the new UserAuthDetails row.
Right now I'm (getting away with) hardcoding roles (and other metadata) and applying them during OnAuthenticated. At some point I might have to reluctantly move this to a table in the database so I can add pre-emptive access assignment during runtime.
Ideally I should be able to pre-create UserAuth rows with the appropriates Roles and Permissions that anticipate that users login using a provider that matches the email. Can I add this functionality through ServiceStack's extension mechanisms without actually modifying the underlying AuthenticateService?
Unless you know exactly what UserAuth to create, I'd still modify them in OnAuthenticated() but you can source them from a custom CreateRole table which lists the Role that should be created against a users Email that way you can assign it to them when they authenticate, e.g:
public override void OnAuthenticated(IServiceBase authService,
IAuthSession session, IAuthTokens tokens, Dictionary<string, string> authInfo)
{
using (var db = authService.TryResolve<IDbConnectionFactory>().Open())
{
var q = db.From<CreateRole>().Where(x => x.Email == session.Email);
var userRoles = db.Column<string>(q.Select(x => x.Role));
var authRepo = authService.TryResolve<IAuthRepository>();
var userAuth = authRepo.GetUserAuth(session, tokens);
authRepo.AssignRoles(userAuth, roles: userRoles);
}
}

How can I search for ldap fields when using ActiveDirectoryRealm in Apache Shiro?

We use Apache Shiro to authenticate and authorize users using our active directory.
Authenticating the user and mapping groups works just fine using the following config:
adRealm = org.apache.shiro.realm.activedirectory.ActiveDirectoryRealm
adRealm.searchBase = "OU=MYORGANIZATION,DC=MYDOMAIN,DC=COM"
adRealm.groupRolesMap = "CN=SOMEREADGROUP":"read","CN=SOMEMODIFYGROUP":"modify","CN=SOMEADMINGROUP":"admin"
adRealm.url = ldaps://my.ad.url:636
adRealm.systemUsername= systemuser
adRealm.systemPassword= secret
adRealm.principalSuffix= #myorganization.mydomain.com
I can authenticate in Shiro using the following lines:
String user = "someuser";
String password = "somepassword";
Subject currentUser = SecurityUtils.getSubject ();
if (!currentUser.isAuthenticated ()){
UsernamePasswordToken token = new UsernamePasswordToken (user,
password);
token.setRememberMe (true);
currentUser.login (token);
}
We now want to get more user information from our ActiveDirectory. How can I do that using Apache Shiro? I was not able to find anything about it in the documentation.
In the source code of ActiveDirectoryRealm I found this line:
NamingEnumeration answer = ldapContext.search(searchBase, searchFilter, searchArguments, searchCtls);
So the first part of the answer is clear: use the ldapContext to search something in it. But how can I retrieve the LdapContext?
It depends on what you are trying to do. Are you just trying to reuse the context to run a query for something other then authentication or authorization? Or are you trying to change the behavior of the query in the AD realm?
If the latter, you would need to extend the ActiveDirectoryRealm and override the queryForAuthorizationInfo() method.
Are you implementing something that is custom for your environment?
(updated)
A couple things:
The realm has access to the LdapContext in the two touch points: queryForAuthenticationInfo() and queryForAuthorizationInfo(), so if you extend the AD realm or AbstractLdapRealm you should already have it. You could change the query to return other info and add the extra info to your Principal. Then you have access to that info directly from your Subject object.
Your realms, are not required to be singletons.
If you want to do some other sort of user management (email all users with a given role, create a user, etc). Then you could create a LdapContextFactory in your shiro.ini, and use the same instance for multiple objects.
[main]
...
ldapContextFactory = org.apache.shiro.realm.ldap.JndiLdapContextFactory
ldapContextFactory.systemUsername = foobar
ldapContextFactory.systemPassword = barfoo
adRealm = org.apache.shiro.realm.activedirectory.ActiveDirectoryRealm
adRealm.ldapContextFactory = $ldapContextFactory
...
myObject = com.biz.myco.MyObject
myObject.ldapContextFactory = $ldapContextFactory
This would work well if myObject is interacting with other Shiro components, (responding to events, etc), but less so if you need access to it from another framework. You could work around this by some sort of static initialization that builds creates the ldapContextFactory, but in my opinion, this is where the sweet spot of using the shiro.ini ends, and where using Guice or Spring shines.

Can't retrieve user roles

I am trying to return a list of roles back to a mobile client device from the WL server
In the createIdentity method of my LoginModule I added the following code
HashMap<String, Object> customAttributes = new HashMap<String, Object>();
customAttributes.put("AuthenticationDate", new Date());
Set<String> groups = new HashSet<String>();
groups.add("Managers");
groups.add("Users");
UserIdentity identity = new UserIdentity(loginModule, USERNAME, "Fred Flintstone", groups, customAttributes, PASSWORD);
The display Name "Fred Flintstone" gets returned to the mobile device, the custom attributes get returned, but the group information seems to get lost somewhere.
I get the following displayed in the mobile device logs
"BasicAuthRealm":{"userId":"user1","attributes":{"AuthenticationDate":"Thu Nov 14 22:39:35 EST 2013"},"isUserAuthenticated":1,"displayName":"Fred Flintstone"},"WL-Authentication-Success":{"BasicAuthRealm":{"userId":"user1","attributes":{"AuthenticationDate":"Thu Nov 14 22:39:35 EST 2013"},"isUserAuthenticated":1,"displayName":"Fred Flintstone"}},
I am running WL 6.0.0.1 Enterprise edition and running against a Liberty server v8.5.5.0
Any ideas?
The groups object is not sent back to the client after the user successfully authenticates. The only parts of the UserIdentity object that are sent back are the name, displayName, and the attributes. I do not know the reason that the groups aren't sent back. Perhaps the objects purpose was only meant for the server and was never intended to be used by the client.
The unfortunate but easy workaround is to add any information you need to know about your group to your attributes object.

Docebo Api Integration

I am facing an issue with implementing the API to authorize the user and make a session and launch a course.
All the full steps like making a token and passing it with REST API has been done and in the response I am receiving the success in the response token.
Now the issue is that when I am trying opening a course link, it redirects me to the login page despite landing on course. Can you please help set up a session and let me know which API is to be used to make a session so that it doesn't redirects me to the login page.
For those still looking for an answer, I'll show you how to generate a temporary link that will authorize a user and direct them to the desired location in Docebo.
Things you need:
The username.
The SSO secret for the token hash.
-In Docebo: Click APPS and Features on left-hand side. Click Third party integrations. Activate API and SSO, if not already activated. After API and SSO is active, click on its gear icon. Click the check box that starts with "Enable SSO with...". Enter a SSO secret in the box below the checkbox. Save.
Now, for the implementation. I myself used C# for this but hopefully it will be easily translatable to your language of choice (or lack of choice).
The basic idea is this:
1) Create an MD5 hash of three values:
(NOTE: Include commas between the values when generating the hash. Example further below...)
username(lowercase!!!)
time = Seconds since the Unix Epoch in utc.
SSO secret (the one you typed yourself).
2) Get the hex value of the hash.
3) Combine the destination url with the username, time, and hex. Like so:
http[s]://[yourdomain]/lms/index.php?r=site/sso&login_user=[username]&time=[utc
time]&token=[token]{&id_course=[id_course]}{&destination=[destination]}
For my example, I didn't specify a course or a destination.
Here is the above gibberish, in C#:
public string GenerateDoceboSSOLink()
{
string userName = "johnsmith"; //Note the lowercase!!
string domain = "http://my-test.docebosaas.com";
string ssoSecret = "MySSOSecret";
//Getting the seconds since the Unix Epoch
TimeSpan t = (DateTime.UtcNow - new DateTime(1970, 1, 1));
int time = (int)t.TotalSeconds;
//Creating the hash...
MD5 md5 = System.Security.Cryptography.MD5.Create();
//Note the inclusion of the commas!
string input = userName + "," + time + "," + ssoSecret;
byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
byte[] hash = md5.ComputeHash(inputBytes);
//Getting the hex value of the hash.
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hash.Length; i++)
{
sb.Append(hash[i].ToString("X2"));
}
string token = sb.ToString(); //the hex value, which we will call token
//The sso link.
string link = String.Format("{0}/lms/index.php?r=site/sso&login_user={1}&time={2}&token={3}", domain, userName, time, token);
return link;
}
So, I followed this
impossible-to-find documentation that led me to what you see above (I couldn't find the url so I just shared it).

DropboxUnlinkedException but the session already had token inside and user didn't revoke the access

My problem is I have existing user in database which store the key and secret from the first authentication. I wish to reuse it again when I come back. For the first time authentication, everything working fine. I can use every method call from Dropbox API and the Token(key and secret) was stored in database.
I come back to app and get the Token from database, set it to the session, link current session with API.
session = new WebAuthSession(appKeys, ACCESS_TYPE);
api = new DropboxAPI<WebAuthSession>(session);
String userKey = dropboxUserObj.getUserKey(); //Key from database
String userSecret = dropboxUserObj.getUserSecret();//Secret from database
AccessTokenPair userAccessTokenPair = new AccessTokenPair(userKey, userSecret);
session.setAccessTokenPair(userAccessTokenPair);
It return DropboxUnlinkedException to me when I want to get user data from api using
String userDisplayName = api.accountInfo().displayname;
I have checked on debug mode. Api was linked with the current session. The current session stored Appkey and user's token and correct access type. The point that I doubt is I saw "client = null". I maybe forgot something but I check them all, try every possibilities I can think of but it still return me "DropboxUnlinkedException" which mean I haven't set an access token pair on the session and I didn't revoke access for sure.
Please help me figure out...
I added a screenshot maybe it can illustrate my problem