Skip to content

Commit

Permalink
Merge pull request #820 from grxnola/authorization-ha1
Browse files Browse the repository at this point in the history
Add ha1 authentication option to digest authentication
  • Loading branch information
egreenmachine authored Jun 10, 2020
2 parents f41b9c9 + ec81c7e commit dbe3266
Show file tree
Hide file tree
Showing 10 changed files with 44 additions and 9 deletions.
13 changes: 13 additions & 0 deletions docs/api/sip.js.useragentoptions.authorizationha1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [sip.js](./sip.js.md) &gt; [UserAgentOptions](./sip.js.useragentoptions.md) &gt; [authorizationHa1](./sip.js.useragentoptions.authorizationha1.md)

## UserAgentOptions.authorizationHa1 property

Authorization ha1.

<b>Signature:</b>

```typescript
authorizationHa1?: string;
```
1 change: 1 addition & 0 deletions docs/api/sip.js.useragentoptions.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export interface UserAgentOptions
| Property | Type | Description |
| --- | --- | --- |
| [allowLegacyNotifications](./sip.js.useragentoptions.allowlegacynotifications.md) | <code>boolean</code> | If <code>true</code>, the user agent will accept out of dialog NOTIFY. |
| [authorizationHa1](./sip.js.useragentoptions.authorizationha1.md) | <code>string</code> | Authorization ha1. |
| [authorizationPassword](./sip.js.useragentoptions.authorizationpassword.md) | <code>string</code> | Authorization password. |
| [authorizationUsername](./sip.js.useragentoptions.authorizationusername.md) | <code>string</code> | Authorization username. |
| [autoStart](./sip.js.useragentoptions.autostart.md) | <code>boolean</code> | |
Expand Down
2 changes: 1 addition & 1 deletion docs/core/sip.js.sessiondialog.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export declare class SessionDialog extends Dialog implements Session
| [receiveRequest(message)](./sip.js.sessiondialog.receiverequest.md) | | Requests sent within a dialog, as any other requests, are atomic. If a particular request is accepted by the UAS, all the state changes associated with it are performed. If the request is rejected, none of the state changes are performed. https://tools.ietf.org/html/rfc3261\#section-12.2.2 |
| [reConfirm()](./sip.js.sessiondialog.reconfirm.md) | | Re-confirm the dialog. Only matters if handling re-INVITE request. |
| [refer(delegate, options)](./sip.js.sessiondialog.refer.md) | | REFER is a SIP request and is constructed as defined in \[1\]. A REFER request MUST contain exactly one Refer-To header field value. https://tools.ietf.org/html/rfc3515\#section-2.4.1 |
| [reliableSequenceGuard(message)](./sip.js.sessiondialog.reliablesequenceguard.md) | | |
| [reliableSequenceGuard(message)](./sip.js.sessiondialog.reliablesequenceguard.md) | | Guard against out of order reliable provisional responses and retransmissions. Returns false if the response should be discarded, otherwise true. |
| [signalingStateRollback()](./sip.js.sessiondialog.signalingstaterollback.md) | | If not in a stable signaling state, rollback to prior stable signaling state. |
| [signalingStateTransition(message)](./sip.js.sessiondialog.signalingstatetransition.md) | | Update the signaling state of the dialog. |
4 changes: 3 additions & 1 deletion docs/core/sip.js.sessiondialog.reliablesequenceguard.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

## SessionDialog.reliableSequenceGuard() method

Guard against out of order reliable provisional responses and retransmissions. Returns false if the response should be discarded, otherwise true.

<b>Signature:</b>

```typescript
Expand All @@ -14,7 +16,7 @@ reliableSequenceGuard(message: IncomingResponseMessage): boolean;

| Parameter | Type | Description |
| --- | --- | --- |
| message | <code>IncomingResponseMessage</code> | |
| message | <code>IncomingResponseMessage</code> | Incoming response message within this dialog. |

<b>Returns:</b>

Expand Down
1 change: 1 addition & 0 deletions etc/api/sip.js.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -805,6 +805,7 @@ export interface UserAgentDelegate {
// @public
export interface UserAgentOptions {
allowLegacyNotifications?: boolean;
authorizationHa1?: string;
authorizationPassword?: string;
authorizationUsername?: string;
// @deprecated (undocumented)
Expand Down
3 changes: 1 addition & 2 deletions etc/core/sip.js.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ export interface DialogState {
//
// @internal
export class DigestAuthentication {
constructor(loggerFactory: LoggerFactory, username: string | undefined, password: string | undefined);
constructor(loggerFactory: LoggerFactory, ha1: string | undefined, username: string | undefined, password: string | undefined);
authenticate(request: OutgoingRequestMessage, challenge: any, body?: string): boolean;
// (undocumented)
stale: boolean | undefined;
Expand Down Expand Up @@ -921,7 +921,6 @@ export class SessionDialog extends Dialog implements Session {
reinviteUserAgentClient: ReInviteUserAgentClient | undefined;
// (undocumented)
reinviteUserAgentServer: ReInviteUserAgentServer | undefined;
// (undocumented)
reliableSequenceGuard(message: IncomingResponseMessage): boolean;
// (undocumented)
get sessionState(): SessionState;
Expand Down
6 changes: 6 additions & 0 deletions src/api/user-agent-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ export interface UserAgentOptions {
*/
allowLegacyNotifications?: boolean;

/**
* Authorization ha1.
* @defaultValue `""`
*/
authorizationHa1?: string;

/**
* Authorization password.
* @defaultValue `""`
Expand Down
4 changes: 3 additions & 1 deletion src/api/user-agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ export class UserAgent {
private static defaultOptions(): Required<UserAgentOptions> {
return {
allowLegacyNotifications: false,
authorizationHa1: "",
authorizationPassword: "",
authorizationUsername: "",
autoStart: false,
Expand Down Expand Up @@ -664,7 +665,8 @@ export class UserAgent {
? this.options.authorizationUsername
: this.options.uri.user; // if authorization username not provided, use uri user as username
const password = this.options.authorizationPassword ? this.options.authorizationPassword : undefined;
return new DigestAuthentication(this.getLoggerFactory(), username, password);
const ha1 = this.options.authorizationHa1 ? this.options.authorizationHa1 : undefined;
return new DigestAuthentication(this.getLoggerFactory(), ha1, username, password);
},
transportAccessor: () => this.transport
};
Expand Down
16 changes: 13 additions & 3 deletions src/core/messages/digest-authentication.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export class DigestAuthentication {
public stale: boolean | undefined;

private logger: Logger;
private ha1: string | undefined;
private username: string | undefined;
private password: string | undefined;
private cnonce: string | undefined;
Expand All @@ -37,10 +38,16 @@ export class DigestAuthentication {
* @param username - Username.
* @param password - Password.
*/
constructor(loggerFactory: LoggerFactory, username: string | undefined, password: string | undefined) {
constructor(
loggerFactory: LoggerFactory,
ha1: string | undefined,
username: string | undefined,
password: string | undefined
) {
this.logger = loggerFactory.getLogger("sipjs.digestauthentication");
this.username = username;
this.password = password;
this.ha1 = ha1;
this.nc = 0;
this.ncHex = "00000000";
}
Expand Down Expand Up @@ -155,10 +162,13 @@ export class DigestAuthentication {
* Generate Digest 'response' value.
*/
private calculateResponse(body?: string): void {
let ha2;
let ha1, ha2;

// HA1 = MD5(A1) = MD5(username:realm:password)
const ha1 = MD5(this.username + ":" + this.realm + ":" + this.password);
ha1 = this.ha1;
if (ha1 === "" || ha1 === undefined) {
ha1 = MD5(this.username + ":" + this.realm + ":" + this.password);
}

if (this.qop === "auth") {
// HA2 = MD5(A2) = MD5(method:digestURI)
Expand Down
3 changes: 2 additions & 1 deletion test/support/core/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,8 @@ export function makeUserAgentCoreConfigurationFromUserAgent(ua: UserAgent): User
? ua.configuration.authorizationUsername
: ua.configuration.uri.user; // if authorization username not provided, use uri user as username
const password = ua.configuration.authorizationPassword ? ua.configuration.authorizationPassword : undefined;
return new DigestAuthentication(ua.getLoggerFactory(), username, password);
const ha1 = ua.configuration.authorizationHa1 ? ua.configuration.authorizationHa1 : undefined;
return new DigestAuthentication(ua.getLoggerFactory(), ha1, username, password);
},
transportAccessor: () => ua.transport
};
Expand Down

0 comments on commit dbe3266

Please sign in to comment.